帙
  
目录
指数
应用 UML 和模式:面向对象的分析和设计以及迭代开发简介,第 3 版
作者:Craig Larman
 
发行人: Addison Wesley 专业
出版日期: 2004 年 10 月 20 日
国际标准书号: 0-13-148906-2
页面: 736
   


应用 UML 和模式是世界 #1 的业务,并且 大学介绍 “Thinking in Objects” 及其用法 深入了解现实世界的面向对象的分析和设计。建筑 在前两个广受好评的版本中,Craig Larman 更新了 本书全面体现了新的 UML 2 标准,对您有帮助 掌握对象设计的艺术,并促进高影响力, 迭代和熟练的敏捷建模实践。

Applying UML and Patterns is the world's #1 business and college introduction to "thinking in objects"and using that insight in real-world object-oriented analysis and design. Building on two widely acclaimed previous editions, Craig Larman has updated this book to fully reflect the new UML 2 standard, to help you master the art of object design, and to promote high-impact, iterative, and skillful agile modeling practices.

开发人员和学生将学习面向对象的分析,并 设计 (OOA/D) 通过两个内聚的 从头到尾的案例研究。这些案例研究逐步进行 介绍关键技能、基本 OO 原则和模式、UML 表示法和最佳实践。您不仅会学习 UML diagrams您将学习如何在上下文中应用 UML OO 软件开发。

Developers and students will learn object-oriented analysis and design (OOA/D) through three iterations of two cohesive, start-to-finish case studies. These case studies incrementally introduce key skills, essential OO principles and patterns, UML notation, and best practices. You won't just learn UML diagramsyou'll learn how to apply UML in the context of OO software development.

利用他作为导师和 顾问,Larman 帮助您了解进化需求 和用例, 领域对象建模, 责任驱动 设计、基本 OO 设计、分层架构、“四人组” 设计模式、GRASP、迭代方法、敏捷方法 统一流程 (UP) 等等。此版本的内容广泛 改进包括

Drawing on his unsurpassed experience as a mentor and consultant, Larman helps you understand evolutionary requirements and use cases, domain object modeling, responsibility-driven design, essential OO design, layered architectures, "Gang of Four" design patterns, GRASP, iterative methods, an agile approach to the Unified Process (UP), and much more. This edition's extensive improvements include

  • 更加专注于帮助您通过案例掌握 OOA/D 展示关键 OO 原则和模式的研究,同时 应用 UML

  • A stronger focus on helping you master OOA/D through case studies that demonstrate key OO principles and patterns, while also applying the UML

  • UML 2 的新覆盖范围、敏捷建模、测试驱动开发、 和重构

  • New coverage of UML 2, Agile Modeling, Test-Driven Development, and refactoring

  • 许多关于结合迭代和进化的新技巧 使用 OOA/D 进行开发

  • Many new tips on combining iterative and evolutionary development with OOA/D

  • 更新以简化学习,包括新的学习辅助工具和 图形

  • Updates for easier study, including new learning aids and graphics

  • 新的大学教育工作者教学资源

  • New college educator teaching resources

  • 以轻松、敏捷的精神应用 UP 的指导, 与其他迭代方法(如 XP 和 Scrum (争霸)

  • Guidance on applying the UP in a light, agile spirit, complementary with other iterative methods such as XP and Scrum

  • 将 UML 应用于文档编制的技术 架构

  • Techniques for applying the UML to documenting architectures

  • 关于进化需求的新章节,以及更多 更多

  • A new chapter on evolutionary requirements, and much more

应用 UML 和模式(第三版)是一本 清晰实用的思维和设计介绍 对象并创建精心设计、健壮、 并且可维护。

Applying UML and Patterns, Third Edition, is a lucid and practical introduction to thinking and designing with objectsand creating systems that are well crafted, robust, and maintainable.

 

 

   
帙
  
目录
指数
应用 UML 和模式:面向对象的分析和设计以及迭代开发简介,第 3 版
作者:Craig Larman
 
发行人: Addison Wesley 专业
出版日期: 2004 年 10 月 20 日
国际标准书号: 0-13-148906-2
页面: 736
   

 

 

   版权
   对应用 UML 和模式的赞誉
   按主要主题划分的内容
   前言
   前言
      教育工作者和 Web 资源
      目标受众介绍!
      先决条件
      Java 示例,但是......
      书籍组织
      关于作者
      联系
      对上一版本的增强
      确认
      排版约定
      制作说明
   第 1 部分。 介绍
         第 1 章. 面向对象的分析和设计
      第 1.1 节. 您将学到什么?它有用吗?
      第 1.2 节. 最重要的学习目标?
      第 1.3 节. 什么是分析与设计?
      第 1.4 节. 什么是面向对象的分析和设计?
      第 1.5 节. 一个简短的例子
      第 1.6 节. 什么是 UML?
      第 1.7 节. 视觉建模是一件好事
      第 1.8 节. 历史
      第 1.9 节. 推荐的资源
         第 2 章. 迭代、进化和敏捷
      介绍
      第 2.1 节. 什么是 UP?其他方法可以互补吗?
      第 2.2 节. 什么是迭代和进化开发?
      第 2.3 节. 瀑布生命周期呢?
      节 2.4. 如何进行迭代和进化分析和设计?
      第 2.5 节. 什么是风险驱动型迭代规划和客户驱动型迭代规划?
      第 2.6 节. 什么是敏捷方法和态度?
      节 2.7. 什么是敏捷建模?
      节 2.8. 什么是 Agile UP?
      第 2.9 节. 还有其他关键的 UP 实践吗?
      第 2.10 节. 什么是 UP 阶段?
      第 2.11 节. 什么是 UP 学科?
      第 2.12 节. 如何自定义流程?UP 开发案例
      第 2.13 节. 你知道你不理解迭代开发或 UP,当时......
      第 2.14 节. 历史
      第 2.15 节. 推荐的资源
         第 3 章. 案例研究
      介绍
      第 3.1 节. 案例研究涵盖哪些内容,未涵盖哪些内容?
      第 3.2 节. 案例研究策略:迭代开发 + 迭代学习
      第 3.3 节. 案例一:NextGen POS 系统
      第 3.4 节. 案例二:大富翁游戏系统
   第 2 部分。 初始
         第 4 章. Inception is Not the Requirements 阶段
      介绍
      第 4.1 节. 什么是盗梦空间?
      第 4.2 节. 盗梦空间多长时间?
      第 4.3 节. 哪些工件可以在 Inception 中开始?
      第 4.4 节. 你知道你不理解 Inception 的时候......
      第 4.5 节. 开始时有多少 UML?
         第 5 章. 进化要求
      介绍
      第 5.1 节. 定义:要求
      第 5.2 节. 进化式与瀑布式要求
      第 5.3 节. 寻找需求的巧妙方法是什么?
      第 5.4 节. 要求的类型和类别有哪些?
      第 5.5 节. UP Artifacts 中的需求是如何组织的?
      第 5.6 节. 这本书是否包含这些工件的示例?
      节 5.7. 推荐的资源
         第 6 章. 使用案例
      介绍
      第 6.1 节. 例
      第 6.2 节. 定义:什么是参与者、场景和用例?
      第 6.3 节. 用例和用例模型
      第 6.4 节. 动机:为什么选择用例?
      第 6.5 节. 定义:用例是功能需求吗?
      第 6.6 节. 定义:什么是三种参与者?
      第 6.7 节. Notation:三种常见的用例格式是什么?
      节 6.8. 示例:流程销售,全装款式
      第 6.9 节. 各部分是什么意思?
      第 6.10 节. 符号:还有其他格式吗?双柱变体
      第 6.11 节. 指南:以基本的无 UI 样式编写
      第 6.12 节. 指南:编写简洁的用例
      第 6.13 节. 指南:编写黑盒用例
      第 6.14 节. 指南:采用参与者和参与者-目标视角
      第 6.15 节. 指南:如何查找用例
      第 6.16 节. 指南:哪些测试可以帮助找到有用的用例?
      第 6.17 节. 应用 UML:用例图
      第 6.18 节. 应用 UML:活动图
      节 6.19. 动机:用例的其他好处?上下文中的要求
      第 6.20 节。 示例:大富翁游戏
      第 6.21 节. 流程:如何在迭代方法中使用用例?
      第 6.22 节. 历史
      第 6.23 节. 推荐的资源
         第 7 章. 其他要求
      介绍
      其他需求工件
      第 7.1 节. 这些示例的完整性如何?
      第 7.2 节. 指南:我们应该在开始时彻底分析这些吗?
      第 7.3 节. 指南:这些工件应该放在项目网站上吗?
      第 7.4 节. NextGen 示例:(部分)补充规范
      第 7.5 节. 释经评注:补充说明书
      第 7.6 节. NextGen 示例:(部分)视力
      第 7.7 节. 解说: 异象
      第 7.8 节. NextGen 示例:A (部分) 词汇表
      节 7.9. 评论: 词汇表 (Data Dictionary)
      第 7.10 节. NextGen 示例:业务规则(域规则)
      第 7.11 节. 评论:域规则
      第 7.12 节. 过程:迭代方法中的进化要求
      节 7.13. 推荐的资源
   第 3 部分。 Elaboration Iteration 1 基础
         第 8 章. 迭代 1 基础知识
      介绍
      第 8.1 节. 迭代 1 要求和重点:核心 OOA/D 技能
      第 8.2 节. 过程:开始和阐述
      第 8.3 节. 流程:规划下一次迭代
         第 9 章. 域模型
      介绍
      第 9.1 节. 例
      第 9.2 节. 什么是域模型?
      第 9.3 节. 动机:为什么要创建域模型?
      第 9.4 节. 指南:如何创建域模型?
      第 9.5 节. 指南:如何找到概念类?
      第 9.6 节. 示例:查找和绘制概念类
      第 9.7 节. 指南:敏捷建模绘制类图
      第 9.8 节. 指南:敏捷建模在工具中维护模型?
      第 9.9 节. 指南:报表对象在模型中包含 'receipt'?
      第 9.10 节. 指南:像地图制作者一样思考;使用域术语
      第 9.11 节. 指南:如何对虚幻世界进行建模?
      第 9.12 节. 指南:属性与类的常见错误
      第 9.13 节。 指南:何时使用 'Description' 类进行建模?
      第 9.14 节. 协会
      第 9.15 节. 示例:域模型中的关联
      第 9.16 节. 属性
      第 9.17 节. 示例:域模型中的属性
      第 9.18 节. 结论:域模型正确吗?
      第 9.19 节. 过程:迭代和进化域建模
      第 9.20 节. 推荐的资源
         第 10 章. 系统序列图
      介绍
      第 10.1 节. 示例:NextGen SSD
      第 10.2 节. 什么是系统序列图?
      第 10.3 节. 动机:为什么要绘制 SSD?
      第 10.4 节. 应用 UML:序列图
      第 10.5 节. SSD 和用例之间有什么关系?
      第 10.6 节. 如何命名系统事件和操作?
      第 10.7 节. 如何对涉及其他外部系统的 SSD 进行建模?
      第 10.8 节. 在词汇表中放置哪些 SSD 信息?
      第 10.9 节. 示例:Monopoly SSD
      第 10.10 节. 工艺:迭代和进化 SSD
      节 10.11. 历史和推荐资源
         第 11 章. 运营合同
      介绍
      第 11.1 节. 例
      第 11.2 节. 定义:合同的条款是什么?
      第 11.3 节. 定义:什么是系统操作?
      第 11.4 节. 定义:后置条件
      第 11.5 节. 示例:enterItem 后置条件
      第 11.6 节. 指南:我们应该更新域模型吗?
      第 11.7 节. 指南:合约在什么情况下有用?
      第 11.8 节. 指南:如何创建和编写合约
      第 11.9 节. 示例:NextGen POS 合同
      节 11.10. 示例:垄断合同
      第 11.11 节. 应用 UML:操作、协定和 OCL
      第 11.12 节. 流程:UP 内的运营合同
      节 11.13. 历史
      节 11.14. 推荐的资源
         第 12 章. DesignIteratively 的要求
      介绍
      第 12.1 节. 迭代地做正确的事,把事情做对
      第 12.2 节. 激发早期变革
      第 12.3 节. 所有这些分析和建模不是需要数周时间才能完成吗?
         第 13 章. 逻辑体系结构和 UML 包图
      介绍
      第 13.1 节. 例
      第 13.2 节. 什么是逻辑架构?图层呢?
      第 13.3 节. 案例研究的重点是什么?
      节 13.4. 什么是软件架构?
      节 13.5. 应用 UML:包图
      第 13.6 节. 指南:使用图层进行设计
      第 13.7 节. 指南:模型-视图分离原则
      第 13.8 节. SSD、系统操作和层之间有什么联系?
      第 13.9 节. 示例:NextGen 逻辑架构和封装图
      节 13.10. 示例:垄断逻辑架构?
      第 13.11 节. 推荐的资源
         第 14 章. 转到 Object Design
      介绍
      第 14.1 节. 敏捷建模和轻量级 UML 绘图
      第 14.2 节. UML CASE 工具
      第 14.3 节. 编码前绘制 UML 花了多少时间?
      节 14.4. 设计对象:什么是静态建模和动态建模?
      节 14.5. 对象设计技能相对于 UML 表示法技能的重要性
      第 14.6 节. 其他对象设计技术:CRC 卡
         第 15 章. UML 交互图
      介绍
      第 15.1 节. 序列图和通信图
      第 15.2 节. UML 建模新手对交互图的关注不够!
      第 15.3 节. 常见的 UML 交互图表示法
      节 15.4. 基本序列图表示法
      节 15.5. 基本通信图符号
         第 16 章. UML 类图
      介绍
      第 16.1 节. 应用 UML:公共类图表示法
      第 16.2 节. 定义:设计类图
      第 16.3 节. 定义:分类器
      节 16.4. 显示 UML 属性的方法:属性文本和关联线
      第 16.5 节. 注释符号:注释、注释、约束和方法主体
      节 16.6. 操作和方法
      第 16.7 节. 关键字
      节 16.8. 构造型、配置文件和标签
      第 16.9 节. UML 属性和属性字符串
      节 16.10. 泛化、抽象类、抽象运算
      节 16.11. 屬地
      第 16.12 节. 接口
      节 16.13. 组合优于聚合
      第 16.14 节. 约束
      第 16.15 节. 合格协会
      第 16.16 节. 关联类
      节 16.17. 单例类
      节 16.18. 模板类和接口
      第 16.19 节. 用户定义的区间
      第 16.20 节. Active 类
      第 16.21 节. 交互和类图之间有什么关系?
         第 17 章. GRASP:设计具有职责的对象
      第 17.1 节. UML 与设计原则
      第 17.2 节. 对象设计:示例输入、活动和输出
      第 17.3 节. 责任和责任驱动设计
      第 17.4 节. GRASP:基本 OO 设计的方法
      第 17.5 节. 职责图、GRASP 和 UML 图之间有什么联系?
      节 17.6. 什么是模式?
      第 17.7 节. 我们现在在哪里?
      第 17.8 节. 使用 GRASP 进行对象设计的简短示例
      第 17.9 节. 将 GRASP 应用于对象设计
      第 17.10 节. 造物主
      第 17.11 节. 信息专家(或专家)
      节 17.12. 低耦合
      第 17.13 节. 控制器
      第 17.14 节. 高内聚力
      节 17.15. 推荐的资源
         第 18 章. 使用 GRASP 的对象设计示例
      介绍
      第 18.1 节. 什么是用例实现?
      节 18.2. Artifact 注释
      第 18.3 节. 下一步是什么?
      第 18.4 节. NextGen 迭代的用例实现
      第 18.5 节. Monopoly 迭代的用例实现
      第 18.6 节. 过程:迭代和进化对象设计
      节 18.7. 总结
         第 19 章. 为可见性而设计
      介绍
      第 19.1 节. 对象之间的可见性
      节 19.2. 什么是可见性?
         第 20 章. 将设计映射到代码
      介绍
      第 20.1 节. 编程和迭代、进化开发
      第 20.2 节. 将设计映射到代码
      第 20.3 节. 从 DCD 创建类定义
      节 20.4. 从交互图创建方法
      第 20.5 节. 代码中的集合类
      节 20.6. 异常和错误处理
      节 20.7. 定义 Sale.makeLineItem 方法
      节 20.8. 实施顺序
      第 20.9 节. 测试驱动或测试优先开发
      节 20.10. 将设计映射到代码的摘要
      第 20.11 节. NextGen POS 程序解决方案简介
      节 20.12. 垄断计划解决方案简介
         第 21 章. 测试驱动开发和重构
      介绍
      节 21.1. 测试驱动开发
      节 21.2. 重构
      第 21.3 节. 推荐的资源
   第 4 部分。 Elaboration Iteration 2 More Patterns
         第 22 章. UML 工具和 UML 作为蓝图
      介绍
      第 22.1 节. 正向、反向和往返工程
      第 22.2 节. 什么是有价值特征的常见报告?
      节 22.3. 在工具中寻找什么?
      节 22.4. 如果绘制 UML,编码后如何更新图表?
      节 22.5. 推荐的资源
         第 23 章. 快速分析更新
      介绍
      第 23.1 节. 案例研究:NextGen POS
      第 23.2 节. 案例研究:垄断
         第 24 章. 迭代 2More Patterns
      介绍
      第 24.1 节. 从迭代 1 到 2
      第 24.2 节. 迭代 2 的要求和重点:对象设计和模式
         第 25 章. GRASP:更多具有职责的对象
      介绍
      第 25.1 节. 多态性
      第 25.2 节. 纯制造
      节 25.3. 间接
      第 25.4 节. 受保护的变体
         第 26 章. 应用 GoF 设计模式
      介绍
      节 26.1. 适配器 (GoF)
      第 26.2 节. 一些 GRASP 原则作为其他模式的推广
      节 26.3. 设计过程中的“分析”发现:域模型
      第 26.4 节. 厂
      节 26.5. 单例 (GoF)
      节 26.6. 具有不同接口的外部服务问题的结论
      第 26.7 节. 策略 (GoF)
      节 26.8. 复合材料 (GoF) 和其他设计原则
      节 26.9. 立面 (GoF)
      节 26.10. 观察者/发布-订阅/委托事件模型 (GoF)
      第 26.11 节. 结论
      节 26.12. 推荐的资源
   第 5 部分。 细化迭代 3 中级主题
         第 27 章. 迭代 3中间主题
      介绍
      第 27.1 节. 下一代 POS
      第 27.2 节. 垄断
         第 28 章. UML 活动图和建模
      介绍
      第 28.1 节. 例
      节 28.2. 如何应用活动图?
      节 28.3. 更多 UML 活动图表示法
      节 28.4. 指引
      节 28.5. 示例:NextGen 活动图
      节 28.6. 流程:UP 中的活动图
      节 28.7. 背景
         第 29 章. UML 状态机图和建模
      介绍
      第 29.1 节. 例
      节 29.2. 定义:事件、状态和转换
      节 29.3. 如何应用状态机图?
      节 29.4. 更多 UML 状态机图表示法
      第 29.5 节. 示例:使用状态机进行 UI 导航建模
      第 29.6 节. 示例:NextGen 用例状态机图
      节 29.7. 过程:UP 中的状态机图
      第 29.8 节. 推荐的资源
         第 30 章. 关联用例
      介绍
      第 30.1 节. include 关系
      第 30.2 节. 术语:具体、抽象、基础和附加用例
      第 30.3 节. extend 关系
      第 30.4 节. 泛化关系
      第 30.5 节. 用例图
         第 31 章. 更多 SSD 和合同
      介绍
      第 31.1 节. 下一代 POS
         第 32 章. 域模型优化
      介绍
      第 32.1 节. NextGen 域模型的新概念
      第 32.2 节. 普遍化
      第 32.3 节. 定义概念超类和子类
      第 32.4 节. 何时定义 Conceptual 子类?
      第 32.5 节. 何时定义概念超类?
      第 32.6 节. NextGen POS 概念类层次结构
      第 32.7 节. 抽象概念类
      第 32.8 节. 对变化的状态进行建模
      第 32.9 节. 软件中的类层次结构和继承
      第 32.10 节. 关联类
      第 32.11 节. 聚合和组合
      节 32.12. 时间间隔和产品价格修复迭代 1 “错误”
      第 32.13 节. 关联角色名称
      第 32.14 节. 作为概念的角色与关联中的角色
      第 32.15 节. 衍生元素
      节 32.16. 合格的协会
      第 32.17 节. 反身联想
      第 32.18 节. 使用包组织域模型
      第 32.19 节. 示例:垄断域模型优化
         第 33 章. 架构分析
      介绍
      第 33.1 节. 流程:我们什么时候开始架构分析?
      第 33.2 节. 定义:变异和进化点
      第 33.3 节. 架构分析
      第 33.4 节. 架构分析的常见步骤
      第 33.5 节. 科学:建筑因素的识别和分析
      节 33.6. 示例:部分 NextGen POS 架构因子表
      节 33.7. 艺术:建筑因素的解析
      第 33.8 节. 建筑分析中的主题摘要
      第 33.9 节. 流程:UP 中的迭代架构
      第 33.10 节. 推荐的资源
         第 34 章. 逻辑架构优化
      介绍
      第 34.1 节. 示例:NextGen Logical Architecture
      第 34.2 节. 使用 Layers 图案的协作
      第 34.3 节. 其他层图案问题
      节 34.4. 模型-视图分离和“向上”通信
      节 34.5. 推荐的资源
         第 35 章. 使用 GoF Patterns 进行更多对象设计
      介绍
      第 35.1 节. 示例:NextGen POS
      第 35.2 节. 故障转移到本地服务;本地缓存的性能
      第 35.3 节. 处理失败
      节 35.4. 使用代理 (GoF) 故障转移到本地服务
      第 35.5 节. 针对非功能性或质量要求进行设计
      节 35.6. 使用适配器访问外部物理设备
      节 35.7. 相关对象族的抽象工厂 (GoF)
      节 35.8. 使用多态处理付款并自己动手
      第 35.9 节. 示例:大富翁
      第 35.10 节. 结论
         第 36 章. 包装设计
      介绍
      第 36.1 节. 包组织准则
      第 36.2 节. 推荐的资源
         第 37 章. UML 部署和组件图
      第 37.1 节. 部署图
      第 37.2 节. 组件图
         第 38 章. 使用模式设计持久性框架
      介绍
      第 38.1 节. 问题:持久对象
      第 38.2 节. 解决方案:来自 Persistence 框架的 Persistence 服务
      第 38.3 节. 框架
      节 38.4. 持久性服务和框架的要求
      第 38.5 节. 关键思想
      第 38.6 节. 模式:将对象表示为表
      第 38.7 节. UML 数据建模配置文件
      第 38.8 节. 模式:对象标识符
      第 38.9 节. 使用 Facade 访问 Persistence 服务
      第 38.10 节. 映射对象:Database Mapper 或 Database Broker 模式
      第 38.11 节. 使用 Template Method 模式进行框架设计
      第 38.12 节. 使用 Template Method 模式实现
      第 38.13 节. 使用 MapperFactory 配置 Mapper
      第 38.14 节。 模式:缓存管理
      第 38.15 节. 在一个类中合并和隐藏 SQL 语句
      第 38.16 节. 事务状态和状态模式
      第 38.17 节。 使用命令模式设计事务
      第 38.18 节. 使用虚拟代理的延迟具体化
      第 38.19 节。 如何在表中表示关系
      第 38.20 节。 PersistentObject 超类和关注点分离
      第 38.21 节。 未解决的问题
         第 39 章. 记录架构:UML & N+1 View Model
      介绍
      第 39.1 节. SAD 及其建筑视图
      第 39.2 节. 符号:SAD 的结构
      第 39.3 节. 示例:NextGen POS SAD
      节 39.4. 示例:A Jakarta Struts SAD
      第 39.5 节. 流程:迭代架构文档
      第 39.6 节. 推荐的资源
   第 6 部分。 专题
         第 40 章. 有关迭代开发和敏捷项目管理的更多信息
      介绍
      第 40.1 节. 如何规划迭代?
      第 40.2 节. 自适应规划与预测规划
      第 40.3 节. 阶段和迭代计划
      第 40.4 节. 如何使用用例和场景规划迭代?
      第 40.5 节. 早期估计的(不)有效性
      第 40.6 节. 组织项目工件
      节 40.7. 你知道你不理解迭代计划的时候......
      第 40.8 节. 推荐的资源
   书目
   词汇表
       前盖内页
       封底内侧
   指数

 

 

版权

Copyright

作者和出版商在编写本书时已谨慎行事,但不作任何形式的明示或暗示的保证,也不对错误或遗漏承担任何责任。对于与使用此处包含的信息或程序有关或由此引起的附带或间接损害,我们不承担任何责任。

The author and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein.

出版商: John Wait

主编:Don O'Hagan

收购编辑: Paul Petralia

市场经理: Chris Guzikowski

执行编辑:John Fuller

项目编辑:Julie Nahil

制造业买家: Carol Melville

Publisher: John Wait

Editor in Chief: Don O'Hagan

Acquisitions Editor: Paul Petralia

Marketing Manager: Chris Guzikowski

Managing Editor: John Fuller

Project Editor: Julie Nahil

Manufacturing Buyer: Carol Melville

当批量订购用于批量购买或特价销售时,出版商会为这本书提供极好的折扣,其中可能包括电子版本和/或定制封面以及特定于您的业务、培训目标、营销重点和品牌兴趣的内容。欲了解更多信息,请联系:

The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact:

美国企业和政府销售

(800) 382-3419

corpsales@pearsontechgroup.com

     U. S. Corporate and Government Sales

     (800) 382-3419

     corpsales@pearsontechgroup.com

对于美国境外的销售,请联系:

For sales outside the U. S., please contact:

国际销售

international@pearsoned.com

     International Sales

     international@pearsoned.com

请访问我们的网站:www.phptr.com

Visit us on the Web: www.phptr.com

美国国会图书馆出版物编目数据:

Library of Congress Cataloging-in-Publication Data:

拉曼,克雷格。

应用 UML 和模式:面向对象的分析和设计以及

迭代开发简介 / Craig Larman。第 3 版,

p. cm.

包括参考书目和索引。

ISBN 0-13-148906-2 (alk. paper)

1.面向对象的方法(计算机科学) 2.UML(计算机科学) 3.系统

分析。4. 系统设计。I. 标题。



QA76.9.O35 L37 2004

005.1'17--dc22 2004057647

Larman, Craig.

    Applying UML and patterns: an introduction to object-oriented analysis and design and

    iterative development / Craig Larman. 3rd ed.

        p. cm.

        Includes bibliographical references and index.

        ISBN 0-13-148906-2 (alk. paper)

        1. Object-oriented methods (Computer science) 2. UML (Computer science) 3. System

    analysis. 4. System design. I. Title.



    QA76.9.O35 L37 2004

    005.1'17--dc22                                                            2004057647

版权所有 © 2005 Pearson Education, Inc.

Copyright © 2005 Pearson Education, Inc.

保留所有权利。在美国印刷。本出版物受版权保护,在以任何形式或任何方式(电子、机械、影印、录制或类似方式)进行任何禁止的复制、存储在检索系统中或传输之前,必须获得出版商的许可。有关权限的信息,请写信至:

All rights reserved. Printed in the United States of America. This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permissions, write to:

Pearson Education, Inc.

权利和合同部

One Lake Street

Upper Saddle River, NJ 07458

Pearson Education, Inc.

Rights and Contracts Department

One Lake Street

Upper Saddle River, NJ 07458

本书中提及的所有产品或服务均为其各自公司或组织的商标或服务标志。

All products or services mentioned in this book are the trademarks or service marks of their respective companies or organizations.

引用致谢:

Quote acknowledgments:

保罗·埃尔多斯(Paul Erdos):摘自保罗·霍夫曼(Paul Hoffman)的《只爱数字的人》(The Man Who Only Loved Numbers)。

H.G. Wells:经 A.P. Watt Ltd. 许可使用。代表 H.G. Wells 遗产的执行人。

Paul Erdos: From "The Man Who Only Loved Numbers" by Paul Hoffman.

H.G. Wells: Used by permission of A.P. Watt Ltd. On behalf of the Executors of the Estate of H.G. Wells.

在美国马萨诸塞州韦斯特福德的 Courier 用再生纸印刷的文本

Text printed in the United States on recycled paper at Courier in Westford, Massachusetts

2004 年 10 月首次印刷

First printing, October 2004

奉献

Dedication

对于 Julie、Haley 和 Hannah

For Julie, Haley, and Hannah

感谢你们的爱和支持。

Thanks for the love and support.

    应用 UML 和模式的赞誉

    Praise for Applying UML and Patterns

    “这个版本包含了拉曼一贯的准确和深思熟虑的写作。这是一本非常好的书,做得更好。

    Alistair Cockburn,作者,《编写有效的用例幸存的 OO 项目

    "This edition contains Larman's usual accurate and thoughtful writing. It is a very good book made even better."

    Alistair Cockburn, author, Writing Effective Use Cases and Surviving OO Projects

    “人们经常问我哪本书最适合向他们介绍 OO 设计的世界。自从我遇到它以来,应用 UML 和模式一直是我毫无保留的选择。

    Martin Fowler,《UML Distilled and Refactoring》作者

    "People often ask me which is the best book to introduce them to the world of OO design. Ever since I came across it Applying UML and Patterns has been my unreserved choice."

    Martin Fowler, author, UML Distilled and Refactoring

    “这本书将 UML 逐渐引入为一种直观的语言,用于指定对象分析和设计的工件,从而使 UML 的学习变得有趣和实用。这是由专家从业者编写的对 UML 和对象方法的精彩介绍。

    Cris Kobryn,UML 修订任务组和 UML 2.0 工作组主席

    "This book makes learning UML enjoyable and pragmatic by incrementally introducing it as an intuitive language for specifying the artifacts of object analysis and design. It is a well written introduction to UML and object methods by an expert practitioner."

    Cris Kobryn, Chair of the UML Revision Task Force and UML 2.0 Working Group

    “很少有人有解释事情的诀窍。很少有人仍然精通软件分析和设计。Craig Larman 两者兼而有之。

    John Vlissides,《设计模式模式剖面线》作者

    "Too few people have a knack for explaining things. Fewer still have a handle on software analysis and design. Craig Larman has both."

    John Vlissides, author, Design Patterns and Pattern Hatching

      按主要主题划分的内容

      Contents by Major Topics

      这本书逐步介绍一个主题,随着案例研究的展开,分为多个章节。这很有用,但它引入了一个问题:如何找到有关主要主题(例如 OO 设计)的大多数材料?索引是一种解决方案,但粒度很细;此列表提供了另一个。

      This book introduces a topic incrementally, spread out over chapters as the case studies unfold. That's useful, but it introduces a problem: How can you find most material on a major subject (e.g., OO Design)? The Index is one solution, but fine-grained; this listing provides another.

      敏捷实践

      Agile Practices

      什么是敏捷建模?30

      What is Agile Modeling? 30

      什么是 Agile UP?31

      What is an Agile UP? 31

      敏捷建模和轻量级 UML 绘图 214

      Agile Modeling and Lightweight UML Drawing 214

      有关迭代开发和敏捷项目管理的更多信息 673

      More on Iterative Development and Agile Project Management 673

      建筑

      Architecture

      逻辑体系结构和 UML 封装图 197

      Logical Architecture and UML Package Diagrams 197

      建筑分析 541

      Architectural Analysis 541

      逻辑架构优化 559

      Logical Architecture Refinement 559

      包装设计 613

      Package Design 613

      记录架构:UML & N+1视图模型655

      Documenting Architecture: UML & the N+1 View Model 655

      域建模

      Domain Modeling

      域模型 131

      Domain Models 131

      Domain Layer 和 Domain Model 之间有什么关系?206

      What's the Relationship Between the Domain Layer and Domain Model? 206

      域模型优化 507

      Domain Model Refinement 507

      把握

      GRASP

      GRASP:设计具有职责的对象 271

      GRASP: Designing Objects with Responsibilities 271

      GRASP:更多具有职责的对象 413

      GRASP: More Objects with Responsibilities 413

      使用 Polymorphism 和 Do It Myself 处理付款 600

      Handling Payments with Polymorphism and Do It Myself 600

      示例:大富翁 607

      Example: Monopoly 607

      GoF 设计模式

      GoF Design Patterns

      什么是模式?278

      What are Patterns? 278

      应用 GoF 设计模式 435

      Applying GoF Design Patterns 435

      更多使用 GoF Patterns 进行对象设计 579

      More Object Design with GoF Patterns 579

      使用模式设计持久性框架 625

      Designing a Persistence Framework with Patterns 625

      迭代开发

      Iterative Development

      迭代、进化和敏捷 17

      Iterative, Evolutionary, and Agile 17

      进化要求 53

      Evolutionary Requirements 53

      迭代 1基础知识 123

      Iteration 1Basics 123

      DesignIteratively 的要求 195

      Requirements to DesignIteratively 195

      有关迭代开发和敏捷项目管理的更多信息 673

      More on Iterative Development and Agile Project Management 673

      OO 分析

      OO Analysis

      域建模和操作协定

      See Domain Modeling and Operation Contracts

      OO 设计

      OO Design

      GRASP 和 GoF 设计模式

      See GRASP and GoF Design Patterns

      继续进行对象设计 213

      On to Object Design 213

      包装设计 613

      Package Design 613

      运营合同

      Operation Contracts

      运营合同 181

      Operation Contracts 181

      运营合同和用例实现 326

      Operation Contracts and Use Case Realizations 326

      更多 SSD 和合同 501

      More SSDs and Contracts 501

      模式

      Patterns

      GRASP 和 GoF 设计模式

      See GRASP and GoF Design Patterns

      什么是模式?278

      What are Patterns? 278

      编程

      Programming

      将设计映射到 Code 369

      Mapping Designs to Code 369

      测试驱动开发和重构 385

      Test-Driven Development and Refactoring 385

      项目管理

      Project Management

      敏捷实践和迭代开发

      See Agile Practices and Iterative Development

      有关迭代开发和敏捷项目管理的更多信息 673

      More on Iterative Development and Agile Project Management 673

      要求

      Requirements

      使用案例

      See Use Cases

      进化要求 53

      Evolutionary Requirements 53

      其他要求 101

      Other Requirements 101

      DesignIteratively 的要求 195

      Requirements to DesignIteratively 195

      UML 活动图和建模 477

      UML Activity Diagrams and Modeling 477

      UML 状态机图和建模 485

      UML State Machine Diagrams and Modeling 485

      系统序列 dgms

      System Sequence Dgms

      系统序列图 173

      System Sequence Diagrams 173

      SSD、系统操作、交互图和用例实现 324

      SSDs, System Operations, Interaction Diagrams, and Use Case Realizations 324

      更多 SSD 和合同 501

      More SSDs and Contracts 501

      测试

      Testing

      测试驱动开发和重构 385

      Test-Driven Development and Refactoring 385

      UML

      UML

      什么是 UML?11

      What is the UML? 11

      应用 UML:用例图 89

      Applying UML: Use Case Diagrams 89

      域模型 131

      Domain Models 131

      应用 UML:序列图 177

      Applying UML: Sequence Diagrams 177

      应用 UML:包图 201

      Applying UML: Package Diagrams 201

      UML 交互图 221

      UML Interaction Diagrams 221

      UML 类图 249

      UML Class Diagrams 249

      UML 活动图和建模 477

      UML Activity Diagrams and Modeling 477

      UML 状态机图和建模 485

      UML State Machine Diagrams and Modeling 485

      用例图 499

      Use Case Diagrams 499

      UML 部署和组件图 621

      UML Deployment and Component Diagrams 621

      统一流程

      Unified Process

      什么是 Agile UP?31

      What is an Agile UP? 31

      还有其他关键的 UP 实践吗?33

      Are There Other Critical UP Practices? 33

      有关迭代开发和敏捷项目管理的更多信息 673

      More on Iterative Development and Agile Project Management 673

      使用案例

      Use Cases

      使用案例 61

      Use Cases 61

      SSD 和用例之间有什么关系?177

      What is the Relationship Between SSDs and Use Cases? 177

      什么是用例实现?322

      What is a Use Case Realization? 322

      相关用例 493

      Relating Use Cases 493

      如何使用用例和场景规划迭代?676

      How to Plan Iterations with Use Cases and Scenarios? 676

        前言

        Foreword

        编程很有趣,但开发高质量的软件却很困难。在美好的想法、需求或 “愿景” 和有效的软件产品之间,除了编程之外,还有更多的东西。分析和设计,定义如何解决问题,编程什么,以易于沟通、审查、实施和发展的方式捕获此设计,这就是本书的核心。这就是您将学到的。

        Programming is fun, but developing quality software is hard. In between the nice ideas, the requirements or the "vision," and a working software product, there is much more than programming. Analysis and design, defining how to solve the problem, what to program, capturing this design in ways that are easy to communicate, to review, to implement, and to evolve is what lies at the core of this book. This is what you will learn.

        统一建模语言 (UML) 已成为软件设计蓝图的普遍接受的语言。UML 是本书中用于传达设计思想的视觉语言,它强调开发人员如何真正应用经常使用的 UML 元素,而不是晦涩难懂的语言功能。

        The Unified Modeling Language (UML) has become the universally-accepted language for software design blueprints. UML is the visual language used to convey design ideas throughout this book, which emphasizes how developers really apply frequently used UML elements, rather than obscure features of the language.

        模式在构建复杂系统方面的重要性在其他学科中早已得到认可。软件设计模式使我们能够描述设计片段,并重用设计理念,帮助开发人员利用他人的专业知识。模式为抽象的启发式方法、规则和面向对象技术的最佳实践提供了名称和形式。没有一个理性的工程师愿意从零开始,这本书提供了一个易于使用的设计模式调色板。

        The importance of patterns in crafting complex systems has long been recognized in other disciplines. Software design patterns are what allow us to describe design fragments, and reuse design ideas, helping developers leverage the expertise of others. Patterns give a name and form to abstract heuristics, rules and best practices of object-oriented techniques. No reasonable engineer wants to start from a blank slate, and this book offers a palette of readily usable design patterns.

        但是,如果不在软件工程过程的上下文中呈现软件设计,则看起来有点枯燥和神秘。在这个话题上,我很高兴 Craig Larman 在他的新版本中选择接受并引入统一流程,展示了如何以相对简单和低仪式的方式应用它。通过在迭代、风险驱动、以架构为中心的过程中呈现案例研究,Craig 的建议具有现实的背景;他揭示了软件开发中真正发生的事情的动态,并展示了起作用的外部力量。设计活动与其他任务相关联,它们不再表现为纯粹的系统性转换或创造性直觉的脑力活动。Craig 和我都深信迭代开发的好处,您将在整篇文章中看到大量说明。

        But software design looks a bit dry and mysterious when not presented in the context of a software engineering process. And on this topic, I am delighted that for his new edition, Craig Larman has chosen to embrace and introduce the Unified Process, showing how it can be applied in a relatively simple and low-ceremony way. By presenting the case study in an iterative, risk-driven, architecture-centric process, Craig's advice has realistic context; he exposes the dynamics of what really happens in software development, and shows the external forces at play. The design activities are connected to other tasks, and they no longer appear as a purely cerebral activity of systematic transformations or creative intuition. And Craig and I are convinced of the benefits of iterative development, which you will see abundantly illustrated throughout.

        所以对我来说,这本书的成分组合是正确的。您将从一位伟大的老师、一位才华横溢的方法论者和一位向世界各地成千上万的人传授面向对象的分析和设计 (OO 大师) 那里学习一种系统的方法。Craig 在 Unified Process 的上下文中描述了该方法。他逐渐提出了更复杂的设计模式,这将使本书在您面临现实世界的设计挑战时非常方便。他使用了最广泛接受的符号。

        So for me, this book has the right mix of ingredients. You will learn a systematic method to do Object-Oriented Analysis and Design (OOA/D) from a great teacher, a brilliant methodologist, and an "OO guru" who has taught it to thousands around the world. Craig describes the method in the context of the Unified Process. He gradually presents more sophisticated design patternsthis will make the book very handy when you are faced with real-world design challenges. And he uses the most widely accepted notation.

        我很荣幸有机会直接与这本重要著作的作者合作。我喜欢阅读第一版,当他让我审阅他的新版草稿时,我很高兴。我们见过几次面,交换了很多电子邮件。我从 Craig 那里学到了很多东西,甚至了解了我们自己在统一流程上的流程工作,以及如何改进它并在各种组织环境中定位它。我确信,即使您已经熟悉 OOA/D,您也会在阅读本书中学到很多东西。而且,像我一样,你会发现自己回到它,刷新你的记忆,或者从 Craig 的解释和经验中获得进一步的见解。

        I'm honored to have had the opportunity to work directly with the author of this major book. I enjoyed reading the first edition, and was delighted when he asked me to review the draft of his new edition. We met several times and exchanged many e-mails. I have learned much from Craig, even about our own process work on the Unified Process and how to improve it and position it in various organizational contexts. I am certain that you will learn a lot, too, in reading this book, even if you are already familiar with OOA/D. And, like me, you will find yourself going back to it, to refresh your memory, or to gain further insights from Craig's explanations and experience.

        祝您阅读愉快!

        Happy reading!

        列颠哥伦比亚



        大学软件工程 Philippe Kruchten

        教授

        列颠哥伦比亚省温哥华 RUP

        Rational Software

        Rational 研究员和流程开发总监

        Philippe Kruchten

        Professor of Software Engineering, University of British Columbia



        formerly,

        Rational Fellow and Director of Process Development for the RUP

        Rational Software

        Vancouver, British Columbia

          前言

          Preface

          感谢您阅读本书!如果我能回答一个问题,或者咨询或指导一个团队(在 OOA/D、UML、建模、迭代和敏捷方法方面),请通过 www.craiglarman.com 与我联系。

          Thank you for reading this book! If I can answer a question, or for consulting or coaching a team (in OOA/D, UML, modeling, iterative and agile methods) please contact me at www.craiglarman.com.

          这是对面向对象的分析和设计 (OOA/D) 以及迭代开发的相关方面的实用介绍。我很感激以前的版本在世界范围内非常受欢迎。衷心感谢所有读者!

          This is a practical introduction to object-oriented analysis and design (OOA/D), and to related aspects of iterative development. I am grateful that the previous editions were extremely popular worldwide. I sincerely thank all the readers!

          以下是这本书将如何使您受益。

          Here is how the book will benefit you.

          首先,对象技术的使用很普遍,因此掌握 OOA/D 对于您在软件世界中取得成功至关重要。

          First, the use of object technology is widespread, so mastery of OOA/D is critical for you to succeed in the software world.

          设计得好

          design well



          其次,如果你是 OOA/D 的新手,你会在如何进行方面遇到挑战,这是可以理解的;本书提出了一个定义明确的迭代路线图统一流程的敏捷方法,以便您可以逐步完成从需求到代码的流程。

          Second, if you are new to OOA/D, you're understandably challenged about how to proceed; this book presents a well-defined iterative roadmapan agile approach to the Unified Processso that you can move in a step-by-step process from requirements to code.

          了解流程路线图

          learn a process roadmap



          第三,统一建模语言 (UML) 已成为建模的标准表示法,因此能够巧妙地应用它非常有用。

          Third, the Unified Modeling Language (UML) has emerged as the standard notation for modeling, so it's useful to be able to apply it skillfully.

          学习 UML 建模

          learn UML for modeling



          第四,设计模式传达了 OO 设计专家应用的 “最佳实践” 习语。您将学习应用设计模式,包括流行的“四人组”模式和 GRASP 模式。学习和应用 pattern 将加速您对分析和设计的掌握。

          Fourth, design patterns communicate the "best practice" idioms OO design experts apply. You will learn to apply design patterns, including the popular "gang-of-four" patterns, and the GRASP patterns. Learning and applying patterns will accelerate your mastery of analysis and design.

          学习设计模式

          learn design patterns



          第五,本书的结构和重点基于多年的教育经验和指导成千上万的 OOA/D 艺术。它通过提供一种精致、成熟且高效的方法来学习该主题来反映这种体验,因此您在阅读和学习方面的投资得到了优化。

          Fifth, the structure and emphasis in this book are based on years of experience in education and mentoring thousands of people in the art of OOA/D. It reflects that experience by providing a refined, proven, and efficient approach to learning the subject, so your investment in reading and learning is optimized.

          从经验中学习

          learn from experience



          第六,它详尽地研究了两个案例研究,以真实地说明整个 OOA/D 过程,并深入探讨了问题的棘手细节。

          Sixth, it exhaustively examines two case studiesto realistically illustrate the entire OOA/D process, and goes deeply into thorny details of the problem.

          从现实的研究中学习

          learn from a realistic study



          第七,它展示了如何将对象设计工件映射到 Java 中的代码。它还引入了测试驱动开发和重构。

          Seventh, it shows how to map object design artifacts to code in Java. It also introduces test-driven development and refactor.

          设计到代码,带有TDD和重构

          design to code, with TDD & refactoring



          第八,它解释了如何设计分层架构并将 UI 层与领域和技术服务层相关联。

          Eighth, it explains how to design a layered architecture and relate the UI layer to domain and technical services layers.

          分层架构

          layered architecture



          最后,它向您展示如何设计 OO 框架,并将其应用于在数据库中创建持久存储框架。

          Finally, it shows you how to design an OO framework and applies this to the creation of a framework for persistent storage in a database.

          设计框架

          design frameworks



            教育工作者和 Web 资源

            Educator and Web Resources

            您可以在 www.craiglarman.com 上找到感兴趣的相关文章。

            You may find related articles of interest at www.craiglarman.com.

            全世界有数百甚至数千名教师使用这本书;它已被翻译成至少十种语言。在我的网站上有各种教育工作者资源,包括组织成 Microsoft PowerPoint 演示文稿的所有书籍图表、OOA/D PowerPoint 演示文稿示例等。如果您是教育工作者,请与我联系以获取资源。

            Hundreds, if not thousands, of teachers use the book worldwide; it's been translated into at least ten languages. At my website there are a variety of educator resources, including all the book figures organized into Microsoft PowerPoint presentations, sample OOA/D PowerPoint presentations, and more. If you're an educator, please contact me for resources.

            我正在使用这本书从现有教育工作者那里收集材料,以便与其他教育工作者分享。如果您有任何要分享的内容,请与我联系

            I am collecting material from existing educators using the book, to share with other educators. If you have anything to share, please contact me.

              目标受众介绍!

              Intended Audiencean Introduction!

              本书介绍了 OOA/D、相关需求分析以及以 Unified Process 作为示例流程的迭代开发;它不是高级文本。它适用于以下受众:

              This book is an introduction to OOA/D, related requirements analysis, and to iterative development with the Unified Process as a sample process; it is not meant as an advanced text. It is for the following audience:

              • 具有一些 OO 编程经验,但对 OOA/D 不熟悉或相对较新的开发人员和学生。

              • Developers and students with some experience in OO programming, but who are newor relatively newto OOA/D.

              • 学习对象技术的计算机科学或软件工程课程的学生。

              • Students in computer science or software engineering courses studying object technology.

              • 那些对 OOA/D 有一定了解,想要学习 UML 表示法、应用模式或想要加深其分析和设计技能的人。

              • Those with some familiarity in OOA/D who want to learn the UML notation, apply patterns, or who want to deepen their analysis and design skills.

                先决条件

                Prerequisites

                要从本书中受益,必须满足一些先决条件:

                Some prerequisites are assumedand necessaryto benefit from this book:

                • 具备面向对象编程语言(如 Java、C#、C++ 或 Python)的知识和经验。

                • Knowledge and experience in an object-oriented programming language such as Java, C#, C++, or Python.

                • 了解基本的 OO 概念,例如类、实例、接口、多态性、封装和继承。

                • Knowledge of fundamental OO concepts, such as class, instance, interface, polymorphism, encapsulation, and inheritance.

                基本 OO 概念未定义。

                Fundamental OO concepts are not defined.

                  Java 示例,但是......

                  Java Examples, But …

                  总的来说,由于 Java 被广泛熟悉,因此本书提供了 Java 代码示例。但是,所提出的想法适用于大多数(如果不是全部)面向对象的技术,包括 C#、Python 等。

                  In general, the book presents code examples in Java due to its widespread familiarity. However, the ideas presented are applicable to mostif not allobject-oriented technologies, including C#, Python, and so on.

                    书籍组织

                    Book Organization

                    本书组织的总体策略是,分析和设计主题的顺序类似于软件开发项目运行的顺序,贯穿“开始”阶段(统一过程术语),然后是三个迭代(参见图 P.1)。

                    The overall strategy in the organization of this book is that analysis and design topics are introduced in an order similar to that of a software development project running across an "inception" phase (a Unified Process term) followed by three iterations (see Figure P.1).

                    1. 初始阶段章节介绍了需求分析的基础知识。

                    2. The inception phase chapters introduce the basics of requirements analysis.

                    3. 迭代 1 介绍了基本的 OOA/D 以及如何为对象分配职责。

                    4. Iteration 1 introduces fundamental OOA/D and how to assign responsibilities to objects.

                    5. 迭代 2 侧重于对象设计,特别是引入一些使用率较高的 “设计模式”。

                    6. Iteration 2 focuses on object design, especially on introducing some high-use "design patterns."

                    7. 迭代 3 引入了各种主题,例如架构分析和框架设计。

                    8. Iteration 3 introduces a variety of subjects, such as architectural analysis and framework design.

                    图 P.1.本书的组织遵循一个开发项目的组织。



                      关于作者

                      About the Author

                      Craig Larman 担任 Valtech 的首席科学家,Valtech 是一家国际咨询和技能转移公司,在欧洲、亚洲和北美设有分支机构。他还是畅销软件工程和迭代敏捷开发文本 Agile and Iterative Development: A Manager's Guide 的作者。他周游世界,从印第安纳州到印度,指导开发团队和经理。

                      Craig Larman serves as chief scientist for Valtech, an international consulting and skills transfer company with divisions in Europe, Asia, and North America. He is also author of the best-selling software engineering and iterative, agile development text Agile and Iterative Development: A Manager's Guide. He travels worldwide, from Indiana to India, coaching development teams and managers.

                      自 1980 年代中期以来,Craig 已帮助成千上万的开发人员应用 OOA/D、熟练地使用 UML 进行建模,并采用迭代开发实践。

                      Since the mid 1980s, Craig has helped thousands of developers to apply OOA/D, skillful modeling with the UML, and to adopt iterative development practices.

                      在作为流浪街头音乐家的失败职业生涯之后,他在 1970 年代构建了 APL、PL/I 和 CICS 系统。从 1980 年代初开始,在完全康复后,他对人工智能产生了兴趣(他自己的人工智能很少),并使用 Lisp 机器、Lisp、Prolog 和 Smalltalk 构建了知识系统。他还曾在使用 Java、.NET、C++ 和 Smalltalk 构建业务系统的组织中工作。他在自己的兼职乐队 Changing Requirements 中弹吉他很糟糕(以前叫 Requirements,但一些乐队成员改变了......

                      After a failed career as a wandering street musician, he built systems in APL, PL/I, and CICS in the 1970s. Starting in the early 1980safter a full recovery he became interested in artificial intelligence (having little of his own) and built knowledge systems with Lisp machines, Lisp, Prolog, and Smalltalk. He's also worked in organizations that build business systems in Java, .NET, C++, and Smalltalk. He plays bad lead guitar in his very part-time band, the Changing Requirements (it used to be called the Requirements, but some band members changed...).

                      他拥有加拿大温哥华美丽的西蒙弗雷泽大学的计算机科学学士和硕士学位。

                      He holds a B.S. and M.S. in computer science from beautiful Simon Fraser University in Vancouver, Canada.

                        联系

                        Contact

                        您可以通过 craig@craiglarman.comwww.craiglarman.com 联系 Craig。他欢迎读者和教育工作者提出问题,并欢迎演讲、指导和咨询咨询。

                        Craig can be reached at craig@craiglarman.com and www.craiglarman.com. He welcomes questions from readers and educators, and speaking, mentoring, and consulting enquiries.

                          对上一版本的增强

                          Enhancements to the Previous Edition

                          在保留与上一版本相同的核心的同时,此版本在许多方面进行了改进,包括:

                          While retaining the same core as the prior edition, this edition is refined in many ways, including:

                          • UML 2

                          • UML 2

                          • 第二个案例研究

                          • A second case study

                          • 有关迭代和进化开发与 OOA/D 相结合的更多提示

                          • More tips on iterative and evolutionary development combined with OOA/D

                          • 使用新的学习辅助工具和图形重写,以便于学习

                          • Rewritten with new learning aids and graphics for easier study

                          • 新的大学教育工作者教学资源

                          • New college-educator teaching resources

                          • 敏捷建模、测试驱动开发和重构

                          • Agile Modeling, Test-Driven Development, and refactoring

                          • 有关使用 UML 活动图进行流程建模的更多信息

                          • More on process modeling with UML activity diagrams

                          • 以轻松、敏捷的精神应用 UP,与其他迭代方法(如 XP 和 Scrum)相辅相成

                          • Guidance on applying the UP in a light, agile spirit, complementary with other iterative methods such as XP and Scrum

                          • 将 UML 应用于记录体系结构

                          • Applying the UML to documenting architectures

                          • 关于进化需求的新篇章

                          • A new chapter on evolutionary requirements

                          • 使用非常流行的 [Cockburn01]

                          • Refinement of the use case chapters, using the very popular approach of [Cockburn01]

                            确认

                            Acknowledgments

                            首先,感谢我在 Valtech 的朋友和同事,他们是世界级的对象开发人员和迭代开发专家,他们以某种方式为本书做出了贡献、支持或审阅了这本书,包括 Chris Tarr、Tim Snyder、Curtis Hite、Celso Gonzalez、Pascal Roques、Ken DeLong、Brett Schuchert、Ashley Johnson、Chris Jones、Thomas Liou、Darryl Gebert,以及我无法列举的许多人。

                            First, thanks to my friends and colleagues at Valtech, world-class object developers and iterative development experts, who in some way contributed to, supported, or reviewed the book, including Chris Tarr, Tim Snyder, Curtis Hite, Celso Gonzalez, Pascal Roques, Ken DeLong, Brett Schuchert, Ashley Johnson, Chris Jones, Thomas Liou, Darryl Gebert, and many more than I can name.

                            感谢 Philippe Kruchten 撰写前言、审阅和以多种方式提供帮助。

                            To Philippe Kruchten for writing the foreword, reviewing, and helping in many ways.

                            感谢 Martin Fowler 和 Alistair Cockburn 对流程和设计、报价和评论的许多有见地的讨论。

                            To Martin Fowler and Alistair Cockburn for many insightful discussions on process and design, quotes, and reviews.

                            感谢 Oystein Haugen、Cris Kobryn、Jim Rumbaugh 和 Bran Selic 审阅 UML 2 材料。

                            To Oystein Haugen, Cris Kobryn, Jim Rumbaugh, and Bran Selic for reviewing the UML 2 material.

                            感谢 John Vlissides 和 Cris Kobryn 的善意引用。

                            To John Vlissides and Cris Kobryn for the kind quotes.

                            感谢 Chelsea Systems 和 John Gray 帮助解决受其 Java 技术 ChelseaStore POS 系统启发的一些需求。

                            To Chelsea Systems and John Gray for help with some requirements inspired by their Java technology ChelseaStore POS system.

                            感谢 Pete Coad 和 Dave Astels 的意见。

                            To Pete Coad and Dave Astels for their input.

                            非常感谢其他审稿人,包括 Steve Adolph、Bruce Anderson、Len Bass、Gary K. Evans、Al Goerner、Luke Hohmann、Eric Lefebvre、David Nunn 和 Robert J. White。

                            Many thanks to the other reviewers, including Steve Adolph, Bruce Anderson, Len Bass, Gary K. Evans, Al Goerner, Luke Hohmann, Eric Lefebvre, David Nunn, and Robert J. White.

                            感谢 Prentice-Hall 的 Paul Becker 相信第一版将是一个有价值的项目,并感谢 Paul Petralia 指导后来的版本。

                            Thanks to Paul Becker at Prentice-Hall for believing the first edition would be a worthwhile project, and to Paul Petralia for shepherding the later ones.

                            最后,特别感谢 Graham Glass 打开了一扇门。

                            Finally, a special thanks to Graham Glass for opening a door.

                              排版约定

                              Typographical Conventions

                              这是一个新词。这是句子中的 Classmethod 名称。这是作者参考 [Bob67]。

                              This is a new term in a sentence. This is a Class or method name in a sentence. This is an author reference [Bob67].

                                制作说明

                                Production Notes

                                该手稿是使用 Adobe FrameMaker 创建的。所有图纸均使用 Microsoft Visio 完成。正文字体为 New Century Schoolbook。最终的打印图像是使用 Adobe Acrobat Distiller 从 Adobe Universal 驱动程序生成的 PostScript 生成为 PDF。使用 ClearBoard 清理了 UML 墙壁草图照片,用于白板照片。

                                The manuscript was created with Adobe FrameMaker. All drawings were done with Microsoft Visio. The body font is New Century Schoolbook. The final print images were generated as PDF using Adobe Acrobat Distiller, from PostScript generated by the Adobe Universal driver. The UML wall sketch photos were cleaned up with ClearBoard for whiteboard photos.

                                  第 1 章.面向对象的分析和设计

                                  Chapter 1. Object-Oriented Analysis and Design

                                  Le temps est un grand professeur, mais malheureusement il tue tous ses élèves (时间是一位伟大的老师,但不幸的是,它杀死了所有的学生。

                                  赫克托·柏辽兹

                                  Le temps est un grand professeur, mais malheureusement il tue tous ses élèves (Time is a great teacher, but unfortunately it kills all its pupils.)

                                  Hector Berlioz

                                  目标

                                  Objectives

                                  • 描述本书的目标和范围。

                                  • Describe the book goals and scope.

                                  • 定义面向对象的分析和设计 (OOA/D)。

                                  • Define object-oriented analysis and design (OOA/D).

                                  • 举例说明一个简短的 OOA/D 示例。

                                  • Illustrate a brief OOA/D example.

                                  • 概述 UML 和可视化敏捷建模。

                                  • Overview UML and visual agile modeling.



                                    1.1. 您将学到什么?它有用吗?

                                    1.1. What Will You Learn? Is it Useful?

                                    拥有一个好的对象设计意味着什么?本书是帮助开发人员和学生学习面向对象分析和设计 (OOA/D) 核心技能的工具。这些技能对于使用 OO 技术和语言(如 Java 或 C#)创建设计良好、健壮且可维护的软件至关重要。

                                    What does it mean to have a good object design? This book is a tool to help developers and students learn core skills in object-oriented analysis and design (OOA/D). These skills are essential for the creation of well-designed, robust, and maintainable software using OO technologies and languages such as Java or C#.

                                    谚语“拥有锤子并不能使人成为建筑师”这句谚语在对象技术方面尤其适用。了解面向对象的语言(比如 Java)是创建对象系统的必要但不够的第一步。知道如何 “在对象中思考 ”是至关重要的!

                                    The proverb "owning a hammer doesn't make one an architect" is especially true with respect to object technology. Knowing an object-oriented language (such as Java) is a necessary but insufficient first step to create object systems. Knowing how to "think in objects" is critical!

                                    这是在应用统一建模语言 (UML) 和模式时对 OOA/D 的介绍。对于迭代开发,使用统一流程的敏捷方法作为示例迭代流程。它并不意味着高级文本;它强调对基础知识的掌握,例如如何为对象分配职责、常用的 UML 表示法和常见的设计模式。同时,主要是在后面的章节中,材料会发展到一些中级主题,例如框架设计和架构分析。

                                    This is an introduction to OOA/D while applying the Unified Modeling Language (UML) and patterns. And, to iterative development, using an agile approach to the Unified Process as an example iterative process. It is not meant as an advanced text; it emphasizes mastery of the fundamentals, such as how to assign responsibilities to objects, frequently used UML notation, and common design patterns. At the same time, mostly in later chapters, the material progresses to some intermediate-level topics, such as framework design and architectural analysis.

                                    UML 与对象思维

                                    UML vs. Thinking in Objects

                                    这本书不仅仅是关于 UML 的。UML 是一种标准的图表符号。通用表示法很有用,但还有更重要的 OO 内容需要学习,尤其是如何在对象中思考。UML 不是 OOA/D 或方法,它只是图表符号。学习 UML 和 UML CASE 工具是没有用的,但不知道如何创建出色的 OO 设计,或者评估和改进现有的 OO 设计。这是困难而重要的技能。因此,本书是对对象设计的介绍。

                                    The book is not just about UML. The UML is a standard diagramming notation. Common notation is useful, but there are more important OO things to learn especially, how to think in objects. The UML is not OOA/D or a method, it is just diagramming notation. It's useless to learn UML and perhaps a UML CASE tool, but not really know how to create an excellent OO design, or evaluate and improve an existing one. This is the hard and important skill. Consequently, this book is an introduction to object design.

                                    然而,我们需要一种用于 OOA/D 和 “软件蓝图” 的语言,它既可以作为一种思考工具,也作为一种交流形式。因此,本书探讨了如何将 UML 应用于执行 OOA/D 的服务,并介绍了常用的 UML。

                                    Yet, we need a language for OOA/D and "software blueprints," both as a tool of thought and as a form of communication. Therefore, this book explores how to apply the UML in the service of doing OOA/D, and covers frequently used UML.

                                    OOD:原则和模式

                                    OOD: Principles and Patterns

                                    应该如何为对象类分配责任?对象应该如何协作?什么类应该做什么?这些都是系统设计中的关键问题,这本书讲授了经典的 OO 设计比喻:责任驱动设计。此外,设计问题的某些久经考验的解决方案可以(并且已经)表示为最佳实践原则、启发式或称为问题解决公式的模式,这些公式将示例性设计原则编纂成文。这本书通过教授如何应用模式或原则,支持更快地学习和熟练使用这些基本的对象设计习惯用法。

                                    How should responsibilities be allocated to classes of objects? How should objects collaborate? What classes should do what? These are critical questions in the design of a system, and this book teaches the classic OO design metaphor: responsibility-driven design. Also, certain tried-and-true solutions to design problems can be (and have been) expressed as best-practice principles, heuristics, or patternsnamed problem-solution formulas that codify exemplary design principles. This book, by teaching how to apply patterns or principles, supports quicker learning and skillful use of these fundamental object design idioms.

                                    案例研究

                                    Case Studies

                                    OOA/D 的介绍在本书中遵循的一些正在进行的案例研究中进行了说明,深入到分析和设计中,以便考虑并解决实际问题中必须考虑和解决的一些血腥细节。

                                    This introduction to OOA/D is illustrated in some ongoing case studies that are followed throughout the book, going deep enough into the analysis and design so that some of the gory details of what must be considered and solved in a realistic problem are considered, and solved.

                                    使用案例

                                    Use Cases

                                    OOD(和所有软件设计)与需求分析的先决条件活动密切相关,这通常包括编写用例。因此,案例研究从对这些主题的介绍开始,即使它们不是专门面向对象的。

                                    OOD (and all software design) is strongly related to the prerequisite activity of requirements analysis, which often includes writing use cases. Therefore, the case study begins with an introduction to these topics, even though they are not specifically object-oriented.

                                    迭代开发、敏捷建模和敏捷 UP

                                    Iterative Development, Agile Modeling, and an Agile UP

                                    考虑到从需求到实施的许多可能活动,开发人员或团队应该如何进行?需求分析和 OOA/D 需要在一些开发过程的上下文中提出和实践。在这种情况下,使用众所周知的统一流程 (UP) 的敏捷 (轻量级、灵活) 方法作为示例迭代开发过程,其中介绍了这些主题。但是,所涵盖的分析和设计主题在许多方法中都是通用的,在敏捷 UP 的上下文中学习它们并不会使它们对其他方法的适用性无效,例如 Scrum、功能驱动开发、精益开发、Crystal 方法等。

                                    Given many possible activities from requirements through to implementation, how should a developer or team proceed? Requirements analysis and OOA/D needs to be presented and practiced in the context of some development process. In this case, an agile (light, flexible) approach to the well-known Unified Process (UP) is used as the sample iterative development process within which these topics are introduced. However, the analysis and design topics that are covered are common to many approaches, and learning them in the context of an agile UP does not invalidate their applicability to other methods, such as Scrum, Feature-Driven Development, Lean Development, Crystal Methods, and so on.

                                    总之,这本书可以帮助学生或开发人员:

                                    In conclusion, this book helps a student or developer:

                                    • 应用原则和模式来创建更好的对象设计。

                                    • Apply principles and patterns to create better object designs.

                                    • 以 UP 的敏捷方法为例,在分析和设计中迭代遵循一组常见活动。

                                    • Iteratively follow a set of common activities in analysis and design, based on an agile approach to the UP as an example.

                                    • 使用 UML 表示法创建常用图表。

                                    • Create frequently used diagrams in the UML notation.

                                    它在经过多次迭代的长期案例研究的背景下说明了这一点。

                                    It illustrates this in the context of long-running case studies that evolve over several iterations.



                                    图 1.1.涵盖的主题和技能。



                                    许多其他技能也很重要!

                                    Many Other Skills Are Important!

                                    这不是软件的完备之书;它主要是对 OOA/D、UML 和迭代开发的介绍,同时涉及相关主题。构建软件涉及无数其他技能和步骤;例如,可用性工程、用户界面设计和数据库设计是成功的关键。

                                    This isn't the Compleate Booke of Software; it's primarily an introduction to OOA/D, UML, and iterative development, while touching on related subjects. Building software involves myriad other skills and steps; for example, usability engineering, user interface design, and database design are critical to success.

                                      1.2. 最重要的学习目标是什么?

                                      1.2. The Most Important Learning Goal?

                                      在入门 OOA/D 中有许多可能的活动和工件,以及丰富的原则和指南。假设我们必须从这里讨论的所有主题中选择一项实践技能,即“荒岛”技能。那会是什么?

                                      There are many possible activities and artifacts in introductory OOA/D, and a wealth of principles and guidelines. Suppose we must choose a single practical skill from all the topics discussed herea "desert island" skill. What would it be?

                                      OO 开发中的一个关键能力是巧妙地为软件对象分配责任。

                                      A critical ability in OO development is to skillfully assign responsibilities to software objects.



                                      为什么?因为它是一项必须在绘制 UML 图或编程时执行的活动,并且它强烈影响软件组件的健壮性、可维护性和可重用性。

                                      Why? Because it is one activity that must be performedeither while drawing a UML diagram or programmingand it strongly influences the robustness, maintainability, and reusability of software components.

                                      当然,OOA/D 中还有其他重要的技能,但本介绍强调了责任分配,因为它往往是一项具有挑战性的技能(具有许多“自由度”或替代方案),但至关重要。在实际项目中,开发人员可能没有机会执行任何其他建模活动,即“匆忙编写代码”开发过程。然而,即使在这种情况下,分配责任也是不可避免的。

                                      Of course, there are other important skills in OOA/D, but responsibility assignment is emphasized in this introduction because it tends to be a challenging skill to master (with many "degrees of freedom" or alternatives), and yet is vitally important. On a real project, a developer might not have the opportunity to perform any other modeling activitiesthe "rush to code" development process. Yet even in this situation, assigning responsibilities is inevitable.

                                      因此,本书中的设计步骤强调责任分配原则。

                                      Consequently, the design steps in this book emphasize principles of responsibility assignment.

                                      提出并应用了对象设计和责任分配的九项基本原则。它们被组织在一个名为 GRASP of principles 的学习辅助工具中,名称为 Information ExpertCreator

                                      Nine fundamental principles in object design and responsibility assignment are presented and applied. They are organized in a learning aid called GRASP of principles with names such as Information Expert and Creator.



                                        1.3. 什么是分析与设计?

                                        1.3. What is Analysis and Design?

                                        分析强调对问题和需求的调查,而不是解决方案。例如,如果需要一个新的在线交易系统,它将如何使用它?它的功能是什么?

                                        Analysis emphasizes an investigation of the problem and requirements, rather than a solution. For example, if a new online trading system is desired, how will it be used? What are its functions?

                                        “分析” 是一个广义的术语,最有资格的术语,如需求分析(对需求的调查)或面向对象的分析(对领域对象的调查)。

                                        "Analysis" is a broad term, best qualified, as in requirements analysis (an investigation of the requirements) or object-oriented analysis (an investigation of the domain objects).

                                        设计强调满足需求的概念解决方案(在软件和硬件中),而不是其实现。例如,数据库架构和软件对象的描述。设计理念通常排除了对目标消费者来说显而易见的低级或“明显”细节。最终,设计是可以实现的,而实现(如代码)表达了真实而完整的实现设计。

                                        Design emphasizes a conceptual solution (in software and hardware) that fulfills the requirements, rather than its implementation. For example, a description of a database schema and software objects. Design ideas often exclude low-level or "obvious" detailsobvious to the intended consumers. Ultimately, designs can be implemented, and the implementation (such as code) expresses the true and complete realized design.

                                        与分析一样,该术语是最合格的,如面向对象设计数据库设计

                                        As with analysis, the term is best qualified, as in object-oriented design or database design.

                                        有用的分析和设计已经总结在短语 do the right thing (analysis) 和 do the thing right (design) 中。

                                        Useful analysis and design have been summarized in the phrase do the right thing (analysis), and do the thing right (design).

                                          1.4. 什么是面向对象的分析和设计?

                                          1.4. What is Object-Oriented Analysis and Design?

                                          在面向对象的分析过程中,强调在问题域中查找和描述对象或概念。例如,在飞行信息系统的情况下,一些概念包括 Plane、FlightPilot

                                          During object-oriented analysis there is an emphasis on finding and describing the objectsor conceptsin the problem domain. For example, in the case of the flight information system, some of the concepts include Plane, Flight, and Pilot.

                                          面向对象设计(或简称对象设计)期间,强调定义软件对象以及它们如何协作以满足需求。例如,Plane 软件对象可能具有 tailNumber 属性和 getFlightHistory 方法(参见图 1.2)。

                                          During object-oriented design (or simply, object design) there is an emphasis on defining software objects and how they collaborate to fulfill the requirements. For example, a Plane software object may have a tailNumber attribute and a getFlightHistory method (see Figure 1.2).

                                          图 1.2.面向对象强调对象的表示。



                                          最后,在实现或面向对象编程期间,将实现设计对象,例如 Java 中的 Plane 类。

                                          Finally, during implementation or object-oriented programming, design objects are implemented, such as a Plane class in Java.

                                            1.5. 一个简短的例子

                                            1.5. A Short Example

                                            在深入探讨迭代开发、需求分析、UML 和 OOA/D 的细节之前,本节使用一个简单的示例“骰子游戏”,其中软件模拟玩家掷两个骰子,简要介绍了几个关键步骤和图表。如果总点数为 7,则他们获胜;否则,他们就输了。

                                            Before diving into the details of iterative development, requirements analysis, UML, and OOA/D, this section presents a bird's-eye view of a few key steps and diagrams, using a simple examplea "dice game" in which software simulates a player rolling two dice. If the total is seven, they win; otherwise, they lose.

                                            定义用例

                                            Define Use Cases

                                            需求分析可能包括人们如何使用应用程序的故事或场景;这些可以编写为用例

                                            Requirements analysis may include stories or scenarios of how people use the application; these can be written as use cases.

                                            用例不是面向对象的工件,它们只是编写的故事。但是,它们是需求分析中的常用工具。例如,以下是 Play a Dice Game 用例的简要版本:

                                            Use cases are not an object-oriented artifactthey are simply written stories. However, they are a popular tool in requirements analysis. For example, here is a brief version of the Play a Dice Game use case:

                                            玩骰子游戏:玩家要求掷骰子。系统显示结果:如果骰子面值总点数为 7,则玩家获胜;否则,玩家输。

                                            Play a Dice Game: Player requests to roll the dice. System presents results: If the dice face value totals seven, player wins; otherwise, player loses.

                                            定义域模型

                                            Define a Domain Model

                                            面向对象的分析涉及从对象的角度创建域的描述。其中确定了被认为值得注意的概念、属性和关联。

                                            Object-oriented analysis is concerned with creating a description of the domain from the perspective of objects. There is an identification of the concepts, attributes, and associations that are considered noteworthy.

                                            结果可以用一个域模型来表示,该模型显示了值得注意的域概念或对象。

                                            The result can be expressed in a domain model that shows the noteworthy domain concepts or objects.

                                            例如,部分域模型如图 1.3 所示。

                                            For example, a partial domain model is shown in Figure 1.3.

                                            图 1.3.骰子游戏的 Partial domain 模型。



                                            此模型说明了值得注意的概念 Player、DieDiceGame 及其关联和属性。

                                            This model illustrates the noteworthy concepts Player, Die, and DiceGame, with their associations and attributes.

                                            请注意,域模型不是软件对象的描述;它是现实世界领域的概念或心智模型的可视化。因此,它也被称为概念对象模型

                                            Note that a domain model is not a description of software objects; it is a visualization of the concepts or mental models of a real-world domain. Thus, it has also been called a conceptual object model.

                                            分配对象职责并绘制交互图

                                            Assign Object Responsibilities and Draw Interaction Diagrams

                                            面向对象设计关注定义软件对象、它们的职责和协作。说明这些协作的一种常见表示法是序列图(一种 UML 交互图)。它显示了软件对象之间的消息流,从而显示了方法的调用。

                                            Object-oriented design is concerned with defining software objectstheir responsibilities and collaborations. A common notation to illustrate these collaborations is the sequence diagram (a kind of UML interaction diagram). It shows the flow of messages between software objects, and thus the invocation of methods.

                                            例如,图 1.4 中的序列图通过向 DiceGameDie 类的实例发送消息来说明一个 OO 软件设计。请注意,这说明了应用 UML 的一种常见实际方式:在白板上绘制草图。

                                            For example, the sequence diagram in Figure 1.4 illustrates an OO software design, by sending messages to instances of the DiceGame and Die classes. Note this illustrates a common real-world way the UML is applied: by sketching on a whiteboard.

                                            图 1.4.说明软件对象之间消息的序列图。



                                            请注意,尽管在现实世界中是玩家掷骰子,但在软件设计中,DiceGame 对象会“掷”骰子(即,向 Die 对象发送消息)。软件对象设计和程序确实从现实世界的领域中汲取了一些灵感,但它们不是现实世界的直接模型或模拟。

                                            Notice that although in the real world a player rolls the dice, in the software design the DiceGame object "rolls" the dice (that is, sends messages to Die objects). Software object designs and programs do take some inspiration from real-world domains, but they are not direct models or simulations of the real world.

                                            定义 Design 类图

                                            Define Design Class Diagrams

                                            除了交互图中显示的协作对象的动态视图外,类定义的静态视图还与设计类图一起有用地显示。这说明了类的属性和方法。

                                            In addition to a dynamic view of collaborating objects shown in interaction diagrams, a static view of the class definitions is usefully shown with a design class diagram. This illustrates the attributes and methods of the classes.

                                            例如,在骰子游戏中,检查序列图会得到图 1.5 所示的部分设计类图。由于播放消息是发送到 DiceGame 对象,因此 DiceGame 类需要一个 play 方法,而类 Die 需要一个 rollgetFaceValue 方法。

                                            For example, in the dice game, an inspection of the sequence diagram leads to the partial design class diagram shown in Figure 1.5. Since a play message is sent to a DiceGame object, the DiceGame class requires a play method, while class Die requires a roll and getFaceValue method.

                                            图 1.5.部分设计类图。



                                            与显示实际类的域模型相反,此图显示了软件类。

                                            In contrast to the domain model showing real-world classes, this diagram shows software classes.

                                            请注意,尽管此设计类图与域模型不同,但某些类名和内容相似。通过这种方式,OO 设计和语言可以支持软件组件和我们的领域心智模型之间的较小表示差距。这提高了理解力。

                                            Notice that although this design class diagram is not the same as the domain model, some class names and content are similar. In this way, OO designs and languages can support a lower representational gap between the software components and our mental models of a domain. That improves comprehension.

                                            总结

                                            Summary

                                            骰子游戏是一个简单的问题,主要集中在分析和设计中的几个步骤和工件上。为了使介绍简单,并未解释所有图示的 UML 表示法。后续章节将更详细地探讨分析和设计以及这些工件。

                                            The dice game is a simple problem, presented to focus on a few steps and artifacts in analysis and design. To keep the introduction simple, not all the illustrated UML notation was explained. Future chapters explore analysis and design and these artifacts in closer detail.

                                              1.6. 什么是 UML?

                                              1.6. What is the UML?

                                              引用:

                                              To quote:

                                              统一建模语言是一种可视化语言,用于指定、构建和记录系统的工件 [OMG03a]。

                                              The Unified Modeling Language is a visual language for specifying, constructing and documenting the artifacts of systems [OMG03a].

                                              定义中的“视觉”一词是一个关键点UML 是事实上的标准图表符号,用于绘制或呈现与软件(主要是 OO 软件)相关的图片(带有一些文本)。

                                              The word visual in the definition is a key pointthe UML is the de facto standard diagramming notation for drawing or presenting pictures (with some text) related to softwareprimarily OO software.

                                              这本书并未涵盖 UML 的所有细微方面,UML 是一大堆符号。它侧重于常用的图表、其中最常用的功能,以及在未来的 UML 版本中不太可能改变的核心表示法。

                                              This book doesn't cover all minute aspects of the UML, a large body of notation. It focuses on frequently used diagrams, the most commonly used features within those, and core notation that is unlikely to change in future UML versions.

                                              UML 定义了各种 UML 配置文件,这些配置文件专门用于公共主题领域的表示法子集,例如,绘制 Enterprise JavaBeans(使用 UML EJB 配置文件)。

                                              The UML defines various UML profiles that specialize subsets of the notation for common subject areas, such as diagramming Enterprise JavaBeans (with the UML EJB profile).

                                              在更深的层次上,模型驱动架构 (MDA) CASE 工具供应商主要感兴趣的是 UML 表示法的基础是描述建模元素语义的 UML 元模型。这不是开发人员需要学习的东西。

                                              At a deeper levelprimarily of interest to Model Driven Architecture (MDA) CASE tool vendorsunderlying the UML notation is the UML meta-model that describes the semantics of the modeling elements. It isn't something a developer needs to learn.

                                              应用 UML 的三种方法

                                              Three Ways to Apply UML

                                              在 [Fowler03] 中,介绍了人们应用 UML 的三种方式:

                                              In [Fowler03] three ways people apply UML are introduced:

                                              • 作为草图的 UML非正式和不完整的图表(通常在白板上手绘)旨在探索问题或解决方案空间的困难部分,利用视觉语言的力量。

                                              • UML as sketch Informal and incomplete diagrams (often hand sketched on whiteboards) created to explore difficult parts of the problem or solution space, exploiting the power of visual languages.

                                              • UML 作为蓝图相对详细的设计图,用于 1) 逆向工程以可视化和更好地理解 UML 图中的现有代码,或 2) 代码生成(正向工程)。

                                              • UML as blueprint Relatively detailed design diagrams used either for 1) reverse engineering to visualize and better understanding existing code in UML diagrams, or for 2) code generation (forward engineering).

                                              • UML 和“银弹”思维

                                                1986 年有一篇著名的论文,题为“没有银弹”,由 Frederick Brooks 博士撰写,也发表在他的经典著作 Mythical Man-Month(20周年纪念版)中。推荐阅读!一个关键的点是,认为软件中存在某种特殊的工具或技术会在生产力、减少缺陷、可靠性或简单性方面产生巨大的数量级差异,这是一个根本性的错误(到目前为止,无休止地重复)。工具并不能弥补设计的无知

                                                然而,您通常会听到来自工具供应商的说法,即绘制 UML 图会让事情变得更好;或者,基于 UML 的模型驱动架构 (MDA) 工具将成为突破性的灵丹妙药。

                                                现实检查时间。UML 只是一个标准的图表符号框、线条等。使用通用符号进行可视化建模可能是一个很大的帮助,但它几乎不如知道如何设计和思考对象重要。这种设计知识是一项非常不同且更重要的技能,不是通过学习 UML 表示法或使用 CASE 或 MDA 工具来掌握的。一个没有好的 OO 设计和编程技能的人画 UML 只是画了糟糕的设计。我建议阅读文章 UML Fever 之死 [Bell04](由 UML 创建者 Grady Booch 认可)以了解有关此主题的更多信息,以及 UML 是什么和不是什么 [Larman04]。

                                                因此,本书介绍了 OOA/D 以及应用 UML 来支持熟练的 OO 设计。



                                                • 如果进行逆向工程,则 UML 工具会读取源或二进制文件,并生成(通常)UML 包、类和序列图。这些 “蓝图” 可以帮助读者理解大局元素、结构和协作。

                                                • 在编程之前,一些详细的图表可以为代码生成(例如,在 Java 中)提供指导,可以手动或使用工具自动生成。通常,这些图表用于某些代码,而其他代码则由开发人员在编码时填写(可能还应用 UML 草图)。

                                              • UML and "Silver Bullet" Thinking

                                                There is a well-known paper from 1986 titled "No Silver Bullet" by Dr. Frederick Brooks, also published in his classic book Mythical Man-Month (20th anniversary edition). Recommended reading! An essential point is that it's a fundamental mistake (so far, endlessly repeated) to believe there is some special tool or technique in software that will make a dramatic order-of-magnitude difference in productivity, defect reduction, reliability, or simplicity. And tools don't compensate for design ignorance.

                                                Yet, you will hear claimsusually from tool vendorsthat drawing UML diagrams will make things much better; or, that Model Driven Architecture (MDA) tools based on UML will be the breakthrough silver bullet.

                                                Reality-check time. The UML is simply a standard diagramming notationboxes, lines, etc. Visual modeling with a common notation can be a great aid, but it is hardly as important as knowing how to design and think in objects. Such design knowledge is a very different and more important skill, and is not mastered by learning UML notation or using a CASE or MDA tool. A person not having good OO design and programming skills who draws UML is just drawing bad designs. I suggest the article Death by UML Fever [Bell04] (endorsed by the UML creator Grady Booch) for more on this subject, and also What UML Is and Isn't [Larman04].

                                                Therefore, this book is an introduction to OOA/D and applying the UML to support skillful OO design.



                                                • If reverse engineering, a UML tool reads the source or binaries and generates (typically) UML package, class, and sequence diagrams. These "blueprints" can help the reader understand the big-picture elements, structure, and collaborations.

                                                • Before programming, some detailed diagrams can provide guidance for code generation (e.g., in Java), either manually or automatically with a tool. It's common that the diagrams are used for some code, and other code is filled in by a developer while coding (perhaps also applying UML sketching).

                                              • UML 作为编程语言UML 中软件系统的完整可执行规范。可执行代码将自动生成,但开发人员通常不会看到或修改这些代码;一个只能在 UML “编程语言” 中工作。UML 的这种使用需要一种实用的方法来绘制所有行为或逻辑(可能使用交互或状态图),并且在理论、工具健壮性和可用性方面仍处于开发阶段。

                                              • UML as programming language Complete executable specification of a software system in UML. Executable code will be automatically generated, but is not normally seen or modified by developers; one works only in the UML "programming language." This use of UML requires a practical way to diagram all behavior or logic (probably using interaction or state diagrams), and is still under development in terms of theory, tool robustness and usability.

                                              敏捷建模强调 UML 作为草图;这是应用 UML 的常用方法,通常具有很高的时间投资回报(通常很短)。UML 工具可能很有用,但我鼓励人们也考虑使用敏捷建模方法来应用 UML。

                                              Agile modeling emphasizes UML as sketch; this is a common way to apply the UML, often with a high return on the investment of time (which is typically short). UML tools can be useful, but I encourage people to also consider an agile modeling approach to applying UML.



                                              应用 UML 的三个角度

                                              Three Perspectives to Apply UML

                                              UML 描述原始图类型,例如类图和序列图。它不会将建模视角叠加在这些上面。例如,相同的 UML 类图表示法可用于绘制现实世界中的概念或 Java 中的软件类的图片。

                                              The UML describes raw diagram types, such as class diagrams and sequence diagrams. It does not superimpose a modeling perspective on these. For example, the same UML class diagram notation can be used to draw pictures of concepts in the real world or software classes in Java.

                                              Syntropy 面向对象方法 [CD94] 强调了这一见解。也就是说,相同的符号可以用于三种透视图和类型的模型(图 1.6):

                                              This insight was emphasized in the Syntropy object-oriented method [CD94]. That is, the same notation may be used for three perspectives and types of models (Figure 1.6):

                                              1. 从概念的角度来看,图表被解释为在现实世界或感兴趣的领域中描述事物。

                                              2. Conceptual perspective the diagrams are interpreted as describing things in a situation of the real world or domain of interest.

                                              3. 规范(软件)角度 图表(使用与概念角度相同的表示法)描述软件抽象或具有规范和接口的组件,但没有对特定实现的承诺(例如,不是 C# 或 Java 中的特定类)。

                                              4. Specification (software) perspective the diagrams (using the same notation as in the conceptual perspective) describe software abstractions or components with specifications and interfaces, but no commitment to a particular implementation (for example, not specifically a class in C# or Java).

                                              5. 实现 (软件) 角度 图表描述了特定技术(如 Java)中的软件实现。

                                              6. Implementation (software) perspective the diagrams describe software implementations in a particular technology (such as Java).

                                              图 1.6.UML 的不同视角。



                                              我们已经在图 1.3图 1.5 中看到了这样一个例子,其中使用相同的 UML 类图表示法来可视化域模型和设计模型。

                                              We've already seen an example of this in Figure 1.3 and Figure 1.5, where the same UML class diagram notation is used to visualize a domain model and a design model.

                                              在实践中,规范视角(推迟目标技术,例如 Java 与 .NET)很少用于设计;大多数面向软件的 UML 图都假定实现视角。

                                              In practice, the specification perspective (deferring the target technology, such as Java versus .NET) is seldom used for design; most software-oriented UML diagramming assumes an implementation perspective.

                                              不同角度中“类”的含义

                                              在原始 UML 中,图 1.6 所示的矩形框称为,但这个术语包含各种现象物理事物、抽象概念、软件事物、事件等。[1]

                                              In the raw UML, the rectangular boxes shown in Figure 1.6 are called classes, but this term encompasses a variety of phenomenaphysical things, abstract concepts, software things, events, and so forth.[1]

                                              [1] UML 类是通用 UML 模型元素分类器的一种特殊情况,具有结构特征和/或行为,包括类、参与者、接口和用例。

                                              [1] A UML class is a special case of the general UML model element classifiersomething with structural features and/or behavior, including classes, actors, interfaces, and use cases.

                                              一种方法将替代术语叠加在原始 UML 之上。例如,在 UP 中,当 UML 框在域模型中绘制时,它们称为域概念概念类;Domain Model 显示了一个概念视角。在 UP 中,当 UML 框在 Design Model 中绘制时,它们称为设计类;Design Model (设计模型) 显示建模者所需的规范或实现透视图。

                                              A method superimposes alternative terminology on top of the raw UML. For example, in the UP, when the UML boxes are drawn in the Domain Model, they are called domain concepts or conceptual classes; the Domain Model shows a conceptual perspective. In the UP, when UML boxes are drawn in the Design Model, they are called design classes; the Design Model shows a specification or implementation perspective, as desired by the modeler.

                                              为了清楚起见,本书将使用与 UML 和 UP 一致的类相关术语,如下所示:

                                              To keep things clear, this book will use class-related terms consistent with the UML and the UP, as follows:

                                              • 概念类、现实世界的概念或事物。概念性或基本性的观点。UP 域模型包含概念类。

                                              • Conceptual class real-world concept or thing. A conceptual or essential perspective. The UP Domain Model contains conceptual classes.

                                              • 软件类 表示软件组件的规范或实现视角的类,与过程或方法无关。

                                              • Software class a class representing a specification or implementation perspective of a software component, regardless of the process or method.

                                              • Implementation class (实现类) 以特定 OO 语言 (如 Java) 实现的类。

                                              • Implementation class a class implemented in a specific OO language such as Java.

                                              UML 1 和 UML 2

                                              UML 1 and UML 2

                                              2004 年底,出现了 UML 的一个主要新版本,即 UML 2。本文基于 UML 2;事实上,这里使用的符号是与 UML 2 规范团队的关键成员一起仔细审查的。

                                              Towards the end of 2004 a major new release of the UML emerged, UML 2. This text is based on UML 2; indeed, the notation used here was carefully reviewed with key members of the UML 2 specification team.

                                              为什么我们在几章中没有看到太多的 UML?

                                              Why Won't We See Much UML for a Few Chapters?

                                              这主要不是一本 UML 表示法书,而是一本探索在 OOA/D 和相关需求分析的上下文中应用 UML、模式和迭代过程的更大图景的书。OOA/D 之前通常进行需求分析。因此,前几章介绍了用例和需求分析的重要主题,然后是关于 OOA/D 和更多 UML 细节的章节。

                                              This is not primarily a UML notation book, but one that explores the larger picture of applying the UML, patterns, and an iterative process in the context of OOA/D and related requirements analysis. OOA/D is normally preceded by requirements analysis. Therefore, the initial chapters introduce the important topics of use cases and requirements analysis, which are then followed by chapters on OOA/D and more UML details.

                                                1.7. 可视化建模是一件好事

                                                1.7. Visual Modeling is a Good Thing

                                                冒着显而易见的风险,绘制或阅读 UML 意味着我们更直观地工作,利用我们大脑的力量来快速掌握(主要是)二维盒线符号中的符号、单位和关系。

                                                At the risk of stating the blindingly obvious, drawing or reading UML implies we are working more visually, exploiting our brain's strength to quickly grasp symbols, units, and relationships in (predominantly) 2D box-and-line notations.

                                                这个古老而简单的想法经常在所有 UML 细节和工具中丢失。不应该!图表帮助我们看到或探索更多的大局以及分析或软件元素之间的关系,同时允许我们忽略或隐藏无趣的细节。这就是 UML 或任何图表语言的简单而本质的价值。

                                                This old, simple idea is often lost among all the UML details and tools. It shouldn't be! Diagrams help us see or explore more of the big picture and relationships between analysis or software elements, while allowing us to ignore or hide uninteresting details. That's the simple and essential value of the UMLor any diagramming language.

                                                  1.8. 历史

                                                  1.8. History

                                                  OOA/D 的历史有很多分支,这个简短的概要并不能公正地对待所有贡献者。1960 年代和 1970 年代见证了 OO 编程语言的出现,例如 Simula 和 Smalltalk,其主要贡献者包括 Kristen Nygaard,尤其是创立了 Smalltalk 的富有远见的计算机科学家 Alan Kay。Kay 创造了面向对象编程和个人计算这两个术语并在 Xerox PARC 期间帮助整合了现代 PC 的思想。[2]

                                                  The history of OOA/D has many branches, and this brief synopsis can't do justice to all the contributors. The 1960s and 1970s saw the emergence of OO programming languages, such as Simula and Smalltalk, with key contributors such as Kristen Nygaard and especially Alan Kay, the visionary computer scientist who founded Smalltalk. Kay coined the terms object-oriented programming and personal computing, and helped pull together the ideas of the modern PC while at Xerox PARC.[2]

                                                  [2] Kay 在 1960 年代还是一名研究生时就开始研究 OO 和 PC。1979 年 12 月,在苹果伟大的杰夫·拉斯金(Mac 的主要创造者)的推动下,苹果的联合创始人兼首席执行官史蒂夫·乔布斯 (Steve Jobs) 拜访了施乐 PARC 的 Alan Kay 和研究团队(包括 Kay 愿景的实现者 Dan Ingalls),以演示 Smalltalk 个人电脑。他所看到的位图重叠窗口、OO 编程和联网 PC 的图形 UI 震惊了她带着新的愿景(Raskin 所希望的)回到了 Apple,Apple Lisa 和 Macintosh 诞生了。

                                                  [2] Kay started work on OO and the PC in the 1960s, while a graduate student. In December 1979at the prompting of Apple's great Jef Raskin (the lead creator of the Mac)Steve Jobs, co-founder and CEO of Apple, visited Alan Kay and research teams (including Dan Ingalls, the implementor of Kay's vision) at Xerox PARC for a demo of the Smalltalk personal computer. Stunned by what he sawa graphical UI of bitmapped overlapping windows, OO programming, and networked PCshe returned to Apple with a new vision (the one Raskin hoped for), and the Apple Lisa and Macintosh were born.

                                                  但 OOA/D 在那个时期是非正式的,直到 1982 年,OOD 才作为一个独立的话题出现。当 Grady Booch(也是 UML 的创始人)写了第一篇题为“面向对象设计”的论文时,这个里程碑就出现了,这可能是 [Booch82] 这个术语的创造。许多其他著名的 OOA/D 先驱在 1980 年代发展了他们的想法:Kent Beck、Peter Coad、Don Firesmith、Ivar Jacobson(UML 创始人)、Steve Mellor、Bertrand Meyer、Jim Rumbaugh(UML 创始人)和 Rebecca Wirfs-Brock 等。Meyer 于 1988 年出版了一本早期有影响力的书籍,《面向对象的软件构造》。同年,Mellor 和 Schlaer 出版了《面向对象的系统分析》,创造了面向对象的分析一词。Peter Coad 在 1980 年代后期创建了一个完整的 OOA/D 方法,并于 1990 年和 1991 年出版了两卷《面向对象的分析》和《面向对象的设计》。同样在 1990 年,Wirfs-Brock 和其他人在他们流行的 Designing Object-Oriented Software 中描述了责任驱动的 OOD 设计方法。1991 年出版了两本非常受欢迎的 OOA/D 书籍。其中一篇描述了 Rumbaugh 等人的 OMT 方法,即面向对象的建模和设计。另一个描述了 Booch 方法,即 Object-Oriented Design with Applications。1992 年,Jacobson 出版了流行的面向对象的软件工程,它不仅促进了 OOA/D,还促进了需求的用例。

                                                  But OOA/D was informal through that period, and it wasn't until 1982 that OOD emerged as a topic in its own right. This milestone came when Grady Booch (also a UML founder) wrote the first paper titled Object-Oriented Design, probably coining the term [Booch82]. Many other well-known OOA/D pioneers developed their ideas during the 1980s: Kent Beck, Peter Coad, Don Firesmith, Ivar Jacobson (a UML founder), Steve Mellor, Bertrand Meyer, Jim Rumbaugh (a UML founder), and Rebecca Wirfs-Brock, among others. Meyer published one of the early influential books, Object-Oriented Software Construction, in 1988. And Mellor and Schlaer published Object-Oriented Systems Analysis, coining the term object-oriented analysis, in the same year. Peter Coad created a complete OOA/D method in the late 1980s and published, in 1990 and 1991, the twin volumes Object-Oriented Analysis and Object-Oriented Design. Also in 1990, Wirfs-Brock and others described the responsibility-driven design approach to OOD in their popular Designing Object-Oriented Software. In 1991 two very popular OOA/D books were published. One described the OMT method, Object-Oriented Modeling and Design, by Rumbaugh et al. The other described the Booch method, Object-Oriented Design with Applications. In 1992, Jacobson published the popular Object-Oriented Software Engineering, which promoted not only OOA/D, but use cases for requirements.

                                                  UML 始于 Booch 和 Rumbaugh 于 1994 年的努力,不仅是为了创建一种通用符号,而且是将他们的两种方法(Booch 和 OMT 方法)结合起来。因此,今天 UML 的第一个公开草案被呈现为统一方法。很快,Objectory 方法的创造者 Ivar Jacobson 也加入了 Rational Corporation,作为一个团体,他们被称为三个朋友。正是在这一点上,他们决定缩小他们的工作范围,并专注于一种常见的图表表示法 UML,而不是一种常见的方法。这不仅是一项划定范围的努力;对象管理组(OMG,面向对象相关标准的行业标准机构)被各种工具供应商说服,认为需要一个开放标准。因此,这个过程开始了,由 Mary Loomis 和 Jim Odell 主持的 OMG 工作组组织了导致 1997 年 UML 1.0 的初步工作。许多其他人为 UML 做出了贡献,也许最著名的是 Cris Kobryn,他是 UML 不断改进的领导者。

                                                  The UML started as an effort by Booch and Rumbaugh in 1994 not only to create a common notation, but to combine their two methodsthe Booch and OMT methods. Thus, the first public draft of what today is the UML was presented as the Unified Method. They were soon joined at Rational Corporation by Ivar Jacobson, the creator of the Objectory method, and as a group came to be known as the three amigos. It was at this point that they decided to reduce the scope of their effort, and focus on a common diagramming notationthe UMLrather than a common method. This was not only a de-scoping effort; the Object Management Group (OMG, an industry standards body for OO-related standards) was convinced by various tool vendors that an open standard was needed. Thus, the process opened up, and an OMG task force chaired by Mary Loomis and Jim Odell organized the initial effort leading to UML 1.0 in 1997. Many others contributed to the UML, perhaps most notably Cris Kobryn, a leader in its ongoing refinement.

                                                  UML 已成为面向对象建模的事实和法律标准图表表示法,并在新的 OMG UML 版本中不断得到完善,www.omg.orgwww.uml.org 版本提供。

                                                  The UML has emerged as the de facto and de jure standard diagramming notation for object-oriented modeling, and has continued to be refined in new OMG UML versions, available at www.omg.org or www.uml.org.

                                                    1.9. 推荐资源

                                                    1.9. Recommended Resources

                                                    在后面的章节中,将推荐与特定主题相关的各种 OOA/D 文本,例如 OO 设计。历史部分的书籍都值得研究,并且仍然适用于其核心建议。

                                                    Various OOA/D texts are recommended in later chapters, in relation to specific subjects, such as OO design. The books in the history section are all worth studyand still applicable regarding their core advice.

                                                    一个非常可读和流行的基本 UML 表示法的摘要是 Martin Fowler 的 UML Distilled。强烈推荐;Fowler 以务实和“敏捷”的态度写了许多有用的书。

                                                    A very readable and popular summary of essential UML notation is UML Distilled by Martin Fowler. Highly recommended; Fowler has written many useful books, with a practical and "agile" attitude.

                                                    有关 UML 表示法的详细讨论,Rumbaugh 的 The Unified Modeling Language Reference Manual 是值得的。请注意,本文不是为了学习如何进行对象建模,也不是 OOA/Dit 的 UML 表示法参考。

                                                    For a detailed discussion of UML notation, The Unified Modeling Language Reference Manual by Rumbaugh is worthwhile. Note that this text isn't meant for learning how to do object modeling or OOA/Dit's a UML notation reference.

                                                    有关 UML 当前版本的明确说明,请参见在线 UML 基础结构规范UML 上层结构规范,www.uml.org 或 www.omg.org

                                                    For the definitive description of the current version of the UML, see the on-line UML Infrastructure Specification and UML Superstructure Specification at www.uml.org or www.omg.org.

                                                    Scott Ambler 的 Agile Modeling 中介绍了敏捷建模精神下的可视化 UML 建模。另请参见 www.agilemodeling.com

                                                    Visual UML modeling in an agile modeling spirit is described in Agile Modeling by Scott Ambler. See also www.agilemodeling.com.

                                                    www.cetus-links.orgwww.iturls.com 中有大量指向 OOA/D 方法的链接(英文的 “Software Engineering” 小节,而不是中文部分)。

                                                    There is a large collection of links to OOA/D methods at www.cetus-links.org and www.iturls.com (the large English "Software Engineering" subsection, rather than the Chinese section).

                                                    关于软件模式的书籍很多,但开创性的经典著作是 Gamma、Helm、Johnson 和 Vlissides 合著的 Design Patterns。对于那些学习对象设计的人来说,这确实是必读的。但是,它不是介绍性文本,最好在熟悉对象设计和编程的基础知识后阅读。另请参阅 www.hillside.netwww.iturls.com(英文的 “Software Engineering” 小节)以获取许多模式站点的链接。

                                                    There are many books on software patterns, but the seminal classic is Design Patterns by Gamma, Helm, Johnson, and Vlissides. It is truly required reading for those studying object design. However, it is not an introductory text and is best read after one is comfortable with the fundamentals of object design and programming. See also www.hillside.net and www.iturls.com (the English "Software Engineering" subsection) for links to many pattern sites.

                                                      第 2 章.迭代、进化和敏捷

                                                      Chapter 2. Iterative, Evolutionary, and Agile

                                                      您应该只在希望成功的项目上使用迭代开发。

                                                      马丁·福勒

                                                      You should use iterative development only on projects that you want to succeed.

                                                      Martin Fowler

                                                      目标

                                                      Objectives

                                                      • 为书籍的内容和顺序提供动力。

                                                      • Provide motivation for the content and order of the book.

                                                      • 定义迭代和敏捷的流程。

                                                      • Define an iterative and agile process.

                                                      • 在 Unified Process 中定义基本概念。

                                                      • Define fundamental concepts in the Unified Process.



                                                        介绍

                                                        Introduction

                                                        迭代开发是 OOA/D 最佳实践的核心,本书对此进行了介绍。敏捷建模等敏捷实践是以有效方式应用 UML 的关键。本章介绍这些主题,以及作为一种相对流行的样本迭代方法的 Unified Process。

                                                        Iterative development lies at the heart of how OOA/D is best practiced and is presented in this book. Agile practices such as Agile Modeling are key to applying the UML in an effective way. This chapter introduces these subjects, and the Unified Process as a relatively popular sample iterative method.

                                                        与顺序或“瀑布”生命周期相反,迭代和进化开发涉及在重复周期中对部分系统进行早期编程和测试。它还通常假设开发在详细定义所有需求之前就开始了;反馈用于阐明和改进不断发展的规范。

                                                        Iterative and evolutionary development contrasted with a sequential or "waterfall" lifecycleinvolves early programming and testing of a partial system, in repeating cycles. It also normally assumes development starts before all the requirements are defined in detail; feedback is used to clarify and improve the evolving specifications.

                                                        我们依靠简短的快速开发步骤、反馈和调整来阐明需求和设计。相比之下,瀑布值促进了编程之前的大型前期推测需求和设计步骤。一致地,成功/失败研究表明,瀑布流与软件项目的最高失败率密切相关,并且在历史上由于信念或道听途说而不是具有统计意义的证据而被推广。研究表明,迭代方法与更高的成功率和生产率以及更低的缺陷水平相关。

                                                        We rely on short quick development steps, feedback, and adaptation to clarify the requirements and design. To contrast, waterfall values promoted big up-front speculative requirements and design steps before programming. Consistently, success/failure studies show that the waterfall is strongly associated with the highest failure rates for software projects and was historically promoted due to belief or hearsay rather than statistically significant evidence. Research demonstrates that iterative methods are associated with higher success and productivity rates, and lower defect levels.

                                                          2.1. 什么是 UP?其他方法可以互补吗?

                                                          2.1. What is the UP? Are Other Methods Complementary?

                                                          软件开发过程描述了一种构建、部署和可能维护软件的方法。统一流程 [JBR99] 已成为构建面向对象系统的流行迭代软件开发流程。特别是,Rational Unified ProcessRUP [Kruchten00],它是 Unified Process 的详细改进,已被广泛采用。

                                                          A software development process describes an approach to building, deploying, and possibly maintaining software. The Unified Process [JBR99] has emerged as a popular iterative software development process for building object-oriented systems. In particular, the Rational Unified Process or RUP [Kruchten00], a detailed refinement of the Unified Process, has been widely adopted.

                                                          因为统一流程 (UP) 对于使用 OOA/D 的项目来说是一个相对流行的迭代过程,并且因为必须使用一些过程来引入主题,所以 UP 塑造了这本书的结构。此外,由于 UP 很常见并促进了广泛认可的最佳实践,因此行业专业人士了解它和进入劳动力市场的学生了解它很有用。

                                                          Because the Unified Process (UP) is a relatively popular iterative process for projects using OOA/D, and because some process must be used to introduce the subject, the UP shapes the book's structure. Also, since the UP is common and promotes widely recognized best practices, it's useful for industry professionals to know it, and students entering the workforce to be aware of it.

                                                          UP 非常灵活和开放,并鼓励包括来自其他迭代方法的熟练实践,例如来自极限编程XP)、Scrum 等。例如,XP 的测试驱动开发、重构持续集成实践可以适应 UP 项目。Scrum 的公共项目室(“作战室”)和日常 Scrum 会议练习也可以。引入 UP 并不意味着要低估这些其他方法的价值,恰恰相反。在我的咨询工作中,我鼓励客户理解并采用来自多种方法的有用技术,而不是教条式的“我的方法比你的方法好”的心态。

                                                          The UP is very flexible and open, and encourages including skillful practices from other iterative methods, such as from Extreme Programming (XP), Scrum, and so forth. For example, XP's test-driven development, refactoring and continuous integration practices can fit within a UP project. So can Scrum's common project room ("war room") and daily Scrum meeting practice. Introducing the UP is not meant to downplay the value of these other methodsquite the opposite. In my consulting work, I encourage clients to understand and adopt a blend of useful techniques from several methods, rather than a dogmatic "my method is better than your method" mentality.



                                                          UP 将普遍接受的最佳实践(例如迭代生命周期和风险驱动型开发)组合成一个有凝聚力且文档齐全的流程描述。

                                                          The UP combines commonly accepted best practices, such as an iterative lifecycle and risk-driven development, into a cohesive and well-documented process description.

                                                          总而言之,本章包括 UP 的介绍,原因有三:

                                                          To summarize, this chapter includes an introduction to the UP for three reasons:

                                                          1. UP 是一个迭代过程。迭代开发会影响本书介绍 OOA/D 的方式以及它的最佳实践。

                                                          2. The UP is an iterative process. Iterative development influences how this book introduces OOA/D, and how it is best practiced.

                                                          3. UP 实践为如何做以及如何解释 OOA/D 提供了一个示例结构。这种结构塑造了书籍的结构。

                                                          4. UP practices provide an example structure for how to doand thus how to explainOOA/D. That structure shapes the book structure.

                                                          5. UP 非常灵活,可以应用于轻量级和敏捷的方法,其中包括其他敏捷方法(如 XP 或 Scrum)的实践。

                                                          6. The UP is flexible, and can be applied in a lightweight and agile approach that includes practices from other agile methods (such as XP or Scrum)more on this later.

                                                          这本书介绍了 UP 的敏捷方法,但并未全面覆盖。它强调与 OOA/D 简介和需求分析相关的常见思想和工件。

                                                          This book presents an introduction to an agile approach to the UP, but not complete coverage. It emphasizes common ideas and artifacts related to an introduction to OOA/D and requirements analysis.



                                                          如果我不关心 UP 怎么办?

                                                          What If I Don't Care About the UP?

                                                          UP 用作示例过程,在其中探索迭代和进化需求分析和 OOA/D,因为有必要在某个过程的上下文中引入主题。

                                                          The UP is used as an example process within which to explore iterative and evolutionary requirements analysis and OOA/D, since it's necessary to introduce the subject in the context of some process.

                                                          但是,本书的中心思想如何使用对象思考和设计、应用 UML、使用设计模式、敏捷建模、进化需求分析、编写用例等独立于任何特定过程,并适用于许多现代迭代、进化和敏捷方法,例如 Scrum、精益开发、DSDM、功能驱动开发、自适应软件开发等。

                                                          But the central ideas of this bookhow to think and design with objects, apply UML, use design patterns, agile modeling, evolutionary requirements analysis, writing use cases, and so forthare independent of any particular process, and apply to many modern iterative, evolutionary, and agile methods, such as Scrum, Lean Development, DSDM, Feature-Driven Development, Adaptive Software Development, and more.

                                                            2.2. 什么是迭代和进化发展?

                                                            2.2. What is Iterative and Evolutionary Development?

                                                            UP 和大多数其他现代方法中的一个关键实践是迭代开发。在这种生命周期方法中,开发被组织成一系列简短的、固定长度的(例如,三周)的小型项目,称为迭代;每个系统的结果都是一个经过测试、集成且可执行的 partial 系统。每个迭代都包括其自己的需求分析、设计、实施和测试活动。

                                                            A key practice in both the UP and most other modern methods is iterative development. In this lifecycle approach, development is organized into a series of short, fixed-length (for example, three-week) mini-projects called iterations; the outcome of each is a tested, integrated, and executable partial system. Each iteration includes its own requirements analysis, design, implementation, and testing activities.

                                                            迭代生命周期基于系统通过多次迭代的连续扩展和细化,以循环反馈和适应为核心驱动力,以收敛到合适的系统。系统随着时间的推移、一次又一次的迭代而逐渐增长,因此这种方法也被称为迭代和增量开发(见图 2.1)。因为反馈和适应会发展规范和设计,所以它也被称为迭代和进化开发

                                                            The iterative lifecycle is based on the successive enlargement and refinement of a system through multiple iterations, with cyclic feedback and adaptation as core drivers to converge upon a suitable system. The system grows incrementally over time, iteration by iteration, and thus this approach is also known as iterative and incremental development (see Figure 2.1). Because feedback and adaptation evolve the specifications and design, it is also known as iterative and evolutionary development.

                                                            图 2.1.迭代和进化发展。



                                                            早期的迭代过程思想被称为螺旋发展和进化发展 [Boehm88Gilb88]。

                                                            Early iterative process ideas were known as spiral development and evolutionary development [Boehm88, Gilb88].

                                                            Example

                                                            例如(不是配方),在项目早期的三周迭代中,周一早上可能花一个小时与团队举行启动会议,以阐明迭代的任务和目标。同时,一个人将最后一次迭代的代码逆向工程为 UML 图(通过 CASE 工具),并打印和显示值得注意的图表。该团队在周一的剩余时间里都在白板前工作,两人一组工作,同时进行敏捷建模,绘制用数码相机捕获的粗略 UML 图,并编写一些伪代码和设计说明。剩下的日子花在实现、测试(单元、验收、可用性等)、进一步设计、集成和部分系统的日常构建上。其他活动包括与利益相关者进行演示和评估,以及规划下一次迭代。

                                                            As an example (not a recipe), in a three-week iteration early in the project, perhaps one hour Monday morning is spent in a kickoff meeting with the team clarifying the tasks and goals of the iteration. Meanwhile, one person reverse-engineers the last iteration's code into UML diagrams (via a CASE tool), and prints and displays noteworthy diagrams. The team spends the remainder of Monday at whiteboards, working in pairs while agile modeling, sketching rough UML diagrams captured on digital cameras, and writing some pseudocode and design notes. The remaining days are spent on implementation, testing (unit, acceptance, usability, …), further design, integration, and daily builds of the partial system. Other activities include demonstrations and evaluations with stakeholders, and planning for the next iteration.



                                                            请注意,在这个例子中,既没有急于编写代码,也没有一个漫长的设计步骤,试图在编程之前完善设计的所有细节。关于使用粗略而快速的 UML 绘图进行可视化建模的设计,我们做了一个 “小 ”的预想;也许是半天或一整天,由开发人员在白板上成对进行设计工作 UML 草图。

                                                            Notice in this example that there is neither a rush to code, nor a long drawn-out design step that attempts to perfect all details of the design before programming. A "little" forethought regarding the design with visual modeling using rough and fast UML drawings is done; perhaps a half or full day by developers doing design work UML sketching in pairs at whiteboards.

                                                            每次迭代的结果都是一个可执行但不完整的系统;它尚未准备好交付到生产环境中。在多次迭代之前,系统可能不符合生产部署的条件;例如,10 次或 15 次迭代。

                                                            The result of each iteration is an executable but incomplete system; it is not ready to deliver into production. The system may not be eligible for production deployment until after many iterations; for example, 10 or 15 iterations.

                                                            迭代的输出不是实验性或一次性原型,迭代开发也不是原型设计。相反,输出是最终系统的生产级子集。

                                                            The output of an iteration is not an experimental or throw-away prototype, and iterative development is not prototyping. Rather, the output is a production-grade subset of the final system.

                                                            如何处理迭代项目的更改?

                                                            How to Handle Change on an Iterative Project?

                                                            一本讨论迭代开发的书的副标题是 Embrace Change [Beck00]。这句话让人想起迭代开发的一个关键态度:迭代和进化开发不是通过尝试(未成功)在实现之前(在“瀑布”过程中)完全正确地指定、冻结和“签署”冻结的需求集和设计来对抗软件开发中不可避免的变化,而是基于一种接受变化和适应的态度,将其视为不可避免的,而且确实是必不可少的驱动力。

                                                            The subtitle of one book that discusses iterative development is Embrace Change [Beck00]. This phrase is evocative of a key attitude of iterative development: Rather than fighting the inevitable change that occurs in software development by trying (unsuccessfully) to fully and correctly specify, freeze, and "sign off" on a frozen requirement set and design before implementation (in a "waterfall" process), iterative and evolutionary development is based on an attitude of embracing change and adaptation as unavoidable and indeed essential drivers.

                                                            这并不是说迭代开发和 UP 鼓励不受控制和反应性的 “特性蠕变” 驱动的过程。随后的章节探讨了 UP 如何平衡一方面达成一致和稳定一组需求的需求,另一方面随着利益相关者澄清他们的愿景或市场变化而不断变化的需求。

                                                            This is not to say that iterative development and the UP encourage an uncontrolled and reactive "feature creep"-driven process. Subsequent chapters explore how the UP balances the needon the one handto agree upon and stabilize a set of requirements, withon the other handthe reality of changing requirements, as stakeholders clarify their vision or the marketplace changes.

                                                            每次迭代都涉及选择一小部分需求,并快速设计、实施和测试。在早期迭代中,需求和设计的选择可能并不完全是最终想要的。但是,在所有需求最终确定之前,或者在整个设计被推测性定义之前,迅速迈出一小步的行为会导致来自用户、开发人员和测试(例如负载和可用性测试)的快速反馈反馈。

                                                            Each iteration involves choosing a small subset of the requirements, and quickly designing, implementing, and testing. In early iterations the choice of requirements and design may not be exactly what is ultimately desired. But the act of swiftly taking a small step, before all requirements are finalized, or the entire design is speculatively defined, leads to rapid feedbackfeedback from the users, developers, and tests (such as load and usability tests).

                                                            而这种早期反馈是值得的;该团队不是推测完整、正确的需求或设计,而是从实际构建和测试中挖掘反馈,以获得关键的实践见解和修改或调整对需求或设计的理解的机会。最终用户有机会快速看到部分系统并说:“是的,这就是我要求的,但现在我尝试了,我真正想要的是略有不同的东西。[1]这个“是的......但是“过程并不是失败的标志;相反,早期和频繁的“是的......但是“是一种取得进展并发现对利益相关者真正有价值的方法。然而,这并不是对开发人员不断改变方向的混乱和反应性开发的认可,中间道路是可能的。

                                                            And this early feedback is worth its weight in gold; rather than speculating on the complete, correct requirements or design, the team mines the feedback from realistic building and testing something for crucial practical insight and an opportunity to modify or adapt understanding of the requirements or design. End-users have a chance to quickly see a partial system and say, "Yes, that's what I asked for, but now that I try it, what I really want is something slightly different."[1] This "yes…but" process is not a sign of failure; rather, early and frequent structured cycles of "yes…buts" are a skillful way to make progress and discover what is of real value to the stakeholders. Yet this is not an endorsement of chaotic and reactive development in which developers continually change directiona middle way is possible.

                                                            [1] 或者更有可能的是,“你不明白我想要什么!

                                                            [1] Or more likely, "You didn't understand what I wanted!"

                                                            除了需求澄清之外,负载测试等活动还将证明部分设计和实现是否走在正确的道路上,或者在下一次迭代中是否需要更改核心架构。最好尽早解决和证明风险和关键的设计决策,而不是晚点,迭代开发为此提供了机制。

                                                            In addition to requirements clarification, activities such as load testing will prove if the partial design and implementation are on the right path, or if in the next iteration, a change in the core architecture is required. Better to resolve and prove the risky and critical design decisions early rather than lateand iterative development provides the mechanism for this.

                                                            因此,工作会通过一系列结构化的构建-反馈-适应周期进行。毫不奇怪,在早期迭代中,与系统的 “真实路径” (就其最终需求和设计而言) 的偏差将大于后续迭代。随着时间的推移,系统会向这条路径收敛,如图 2.2 所示。

                                                            Consequently, work proceeds through a series of structured build-feedback-adapt cycles. Not surprisingly, in early iterations the deviation from the "true path" of the system (in terms of its final requirements and design) will be larger than in later iterations. Over time, the system converges towards this path, as illustrated in Figure 2.2.

                                                            图 2.2.迭代反馈和进化导致所需的系统。随着时间的推移,需求和设计的不稳定性会降低。



                                                            迭代开发有什么好处吗?

                                                            Are There Benefits to Iterative Development?

                                                            是的。优势包括:

                                                            Yes. Benefits include:

                                                            • 减少项目失败、提高生产力和降低缺陷率;通过对迭代和进化方法的研究显示

                                                            • less project failure, better productivity, and lower defect rates; shown by research into iterative and evolutionary methods

                                                            • 尽早而不是延迟缓解高风险(技术、要求、目标、可用性等)

                                                            • early rather than late mitigation of high risks (technical, requirements, objectives, usability, and so forth)

                                                            • 早期可见的进展

                                                            • early visible progress

                                                            • 早期反馈、用户参与和适应,从而形成更紧密地满足利益相关者实际需求的精细系统

                                                            • early feedback, user engagement, and adaptation, leading to a refined system that more closely meets the real needs of the stakeholders

                                                            • 可控的复杂性;团队不会被 “分析瘫痪” 或非常漫长而复杂的步骤所淹没

                                                            • managed complexity; the team is not overwhelmed by "analysis paralysis" or very long and complex steps

                                                            • 迭代中的学习可以有条不紊地用于改进开发过程本身,逐个迭代

                                                            • the learning within an iteration can be methodically used to improve the development process itself, iteration by iteration

                                                            迭代应该多长时间?什么是迭代时间盒?

                                                            How Long Should an Iteration Be? What is Iteration Timeboxing?

                                                            大多数迭代方法建议的迭代长度在 2 到 6 周之间。小步骤、快速反馈和适应是迭代开发的中心思想;长时间迭代颠覆了迭代开发的核心动机,增加了项目风险。在短短一周内,通常很难完成足够的工作来获得有意义的吞吐量和反馈;超过 6 周,复杂性变得相当庞大,反馈被延迟。一个非常长的时间盒迭代错过了迭代开发的重点。短就是好。

                                                            Most iterative methods recommend an iteration length between two and six weeks. Small steps, rapid feedback, and adaptation are central ideas in iterative development; long iterations subvert the core motivation for iterative development and increase project risk. In only one week it is often difficult to complete sufficient work to get meaningful throughput and feedback; more than six weeks, and the complexity becomes rather overwhelming, and feedback is delayed. A very long timeboxed iteration misses the point of iterative development. Short is good.

                                                            一个关键思想是迭代是有时间限制的,或者说长度是固定的。例如,如果下一次迭代选择为三周,则必须通过计划的日期日期延迟来集成、测试和稳定部分系统,这是非法的。如果似乎很难满足截止日期,建议的应对措施是从迭代中删除任务或需求,并将它们包含在将来的迭代中,而不是推迟完成日期。

                                                            A key idea is that iterations are timeboxed, or fixed in length. For example, if the next iteration is chosen to be three weeks long, then the partial system must be integrated, tested, and stabilized by the scheduled datedate slippage is illegal. If it seems that it will be difficult to meet the deadline, the recommended response is to de-scoperemove tasks or requirements from the iteration, and include them in a future iteration, rather than slip the completion date.

                                                              2.3. 瀑布生命周期呢?

                                                              2.3. What About the Waterfall Lifecycle?

                                                              瀑布式(或顺序)生命周期过程中,尝试在编程之前定义(详细)所有或大部分需求。通常,在编程之前创建一个全面的设计(或一组 smodel)。同样,试图在开始时定义一个 “可靠 ”的计划或时间表,而不是它将是。

                                                              In a waterfall (or sequential) lifecycle process there is an attempt to define (in detail) all or most of the requirements before programming. And often, to create a thorough design (or set of smodels) before programming. Likewise, an attempt to define a "reliable" plan or schedule near the startnot that it will be.

                                                              警告:在 Iterative 上叠加 Waterfall

                                                              Warning: Superimposing Waterfall on Iterative

                                                              如果您发现自己在一个“迭代”项目中,其中大多数需求是在开发开始之前编写的,或者试图在编程之前创建许多全面而详细的规范或 UML 模型和设计,请知道瀑布式思维不幸地困扰了该项目。无论声明如何,它都不是一个健康的迭代或 UP 项目。

                                                              If you find yourself on an "iterative" project where most of the requirements are written before development begins, or there is an attempt to create many thorough and detailed specifications or UML models and designs before programming, know that waterfall thinking has unfortunately afflicted the project. It is not a healthy iterative or UP project, regardless of claims.



                                                              研究(从许多来源收集并在 [Larman03] 和 [LB03] 中总结)现在最终表明,具有讽刺意味的是,1960 年代和 1970 年代应用瀑布的建议对于大多数软件项目来说是一种糟糕的做法,而不是一种熟练的方法。它与高失败率、低生产率和更高的缺陷率(与迭代项目相比)密切相关。平均而言,瀑布流要求中 45% 的特征从未使用过,早期瀑布流计划和估计值与最终实际值相差高达 400%。

                                                              Research (collected from many sources and summarized in [Larman03] and [LB03]) now shows conclusively that the 1960s and 1970s-era advice to apply the waterfall wasironicallya poor practice for most software projects, rather than a skillful approach. It is strongly associated with high rates of failure, lower productivity, and higher defect rates (than iterative projects). On average, 45% of the features in waterfall requirements are never used, and early waterfall schedules and estimates vary up to 400% from the final actuals.

                                                              特征使用研究,第 56

                                                              feature use research p. 56



                                                              事后看来,我们现在知道瀑布式建议是基于猜测道听途说,而不是基于证据的实践。相比之下,迭代和进化实践有证据支持,研究表明它们不易失败,并且与更高的生产力和缺陷率相关。

                                                              In hindsight, we now know that waterfall advice was based on speculation and hearsay, rather than evidence-based practices. In contrast, iterative and evolutionary practices are backed by evidencestudies show they are less failure prone, and associated with better productivity and defect rates.

                                                              指南:不要让瀑布式思维侵入迭代或 UP 项目

                                                              Guideline: Don't Let Waterfall Thinking Invade an Iterative or UP Project

                                                              我需要强调的是,“瀑布式思维”经常被错误地侵入到所谓的迭代或 UP 项目中。诸如“让我们在开始编程之前编写所有用例”或“让我们在开始编程之前在 UML 中做许多详细的 OO 模型”之类的想法是错误地叠加在 UP 上的不健康的瀑布思维的例子。UP 的创建者将这种误解大前期分析和建模列为其失败的关键原因 [KL01]。

                                                              I need to emphasize that "waterfall thinking" often incorrectly still invades a so-called iterative or UP project. Ideas such as "let's write all the use cases before starting to program" or "let's do many detailed OO models in UML before starting to program" are examples of unhealthy waterfall thinking incorrectly super imposed on the UP. The creators of the UP cite this misunderstandingbig up-front analysis and modelingas a key reason for its failed adoption [KL01].

                                                              为什么瀑布式如此容易失败?

                                                              Why is the Waterfall so Failure-Prone?

                                                              对于瀑布流为何如此容易失败,没有一个简单的答案,但它与许多失败软件项目背后的一个关键错误假设密切相关,即规范是可预测的和稳定的,并且可以在开始时正确定义,更改率低。事实证明,这远非准确,而且是一个代价高昂的误解。Boehm 和 Papaccio 的一项研究表明,一个典型的软件项目的需求发生了 25% 的变化 [BP88]。这一趋势在另一项针对数千个软件项目的主要研究中得到了证实,大型项目的变更率甚至更高 35% 到 50%,如图 2.3 所示 [Jones97]。

                                                              There isn't one simple answer to why the waterfall is so failure-prone, but it is strongly related to a key false assumption underlying many failed software projectsthat the specifications are predictable and stable and can be correctly defined at the start, with low change rates. This turns out to be far from accurateand a costly misunderstanding. A study by Boehm and Papaccio showed that a typical software project experienced a 25% change in requirements [BP88]. And this trend was corroborated in another major study of thousands of software projects, with change rates that go even higher35% to 50% for large projectsas illustrated in Figure 2.3 [Jones97].

                                                              图 2.3.不同规模的软件项目的更改百分比。



                                                              这些是高的更改率。这些数据表明,任何有经验的开发人员或经理都痛苦地意识到,软件开发(平均而言)是一个高度变化和不稳定的领域,也称为新产品开发领域。软件通常不是一个可预测或大规模制造的低变化领域,在这些领域中,在开始时可以有效地定义所有稳定的规范和可靠的计划。

                                                              These are extremely high change rates. What this data showsas any experienced developer or manager is painfully awareis that software development is (on average) a domain of high change and instabilityalso known as the domain of new product development. Software is not usually a domain of predictable or mass manufacturinglow-change areas where it is possible and efficient to define all the stable specifications and reliable plans near the start.

                                                              因此,任何基于事物长期稳定(即瀑布)假设的分析、建模、开发或管理实践都是有根本缺陷的。变化是软件项目的常态。迭代和进化方法根据反馈假设并接受部分和不断发展的规范、模型和计划的变化和适应。

                                                              Thus, any analysis, modeling, development, or management practice based on the assumption that things are long-term stable (i.e., the waterfall) is fundamentally flawed. Change is the constant on software projects. Iterative and evolutionary methods assume and embrace change and adaptation of partial and evolving specifications, models, and plans based on feedback.

                                                              需要反馈和适应

                                                              The Need for Feedback and Adaptation

                                                              在复杂、不断变化的系统中(例如大多数软件项目),反馈和适应是成功的关键因素。

                                                              In complex, changing systems (such as most software projects) feedback and adaptation are key ingredients for success.

                                                              • 来自早期开发的反馈,程序员尝试阅读规范,以及客户演示以完善需求。

                                                              • Feedback from early development, programmers trying to read specifications, and client demos to refine the requirements.

                                                              • 来自测试和开发人员的反馈,以优化设计或模型。

                                                              • Feedback from tests and developers to refine the design or models.

                                                              • 来自团队处理早期功能以优化计划和估计的进度的反馈。

                                                              • Feedback from the progress of the team tackling early features to refine the schedule and estimates.

                                                              • 来自客户和市场的反馈,以重新确定下一次迭代中要解决的功能的优先级。

                                                              • Feedback from the client and marketplace to re-prioritize the features to tackle in the next iteration.

                                                                2.4. 如何进行迭代和进化分析和设计?

                                                                2.4. How to do Iterative and Evolutionary Analysis and Design?

                                                                这个介绍可能给人的印象是,在编程之前进行分析和设计没有价值,但这是一种极端的误解,就像认为“完整”的前期分析是熟练的一样极端。有一条中间道路。这是一个简短的示例(不是配方),说明它如何在运行良好的 UP 项目中工作。这假设在交付之前,项目最终将有 20 次迭代:

                                                                This introduction may have given the impression that there is no value in analysis and design before programming, but that is a misunderstanding as extreme as thinking that "complete" up-front analysis is skillful. There is a middle way. Here's a short example (not a recipe) of how it can work on a well-run UP project. This assumes there will ultimately be 20 iterations on the project before delivery:

                                                                1. 在迭代 1 之前,举行第一次有时间限制的需求研讨会,比如正好两天。业务和开发人员(包括首席架构师)在场。

                                                                  • 在第一天早上,进行高级需求分析,例如仅确定用例和功能的名称,以及关键的非功能性需求。分析不会完美。

                                                                  • 要求首席架构师和业务人员从这个高级列表中挑选 10%(例如 30 个用例名称中的 10%),这些名称混合了以下三种品质:1) 架构上重要(如果实现,我们将被迫设计、构建和测试核心架构),2) 高业务价值(业务真正关心的功能), 3) 高风险(例如“能够处理 500 个并发事务”)。也许因此确定了三个用例:UC2、UC11、UC14。

                                                                  • 在剩下的 1.5 天里,对这三个用例的功能和非功能要求进行深入的详细分析。完成后,10% 被深入分析,90% 只是高级分析。

                                                                2. Before iteration-1, hold the first timeboxed requirements workshop, such as exactly two days. Business and development people (including the chief architect) are present.

                                                                  • On the morning of day one, do high-level requirements analysis, such as identifying just the names of the use cases and features, and key non-functional requirements. The analysis will not be perfect.

                                                                  • Ask the chief architect and business people to pick 10% from this high-level list (such as 10% of the 30 use case names) that have a blending of these three qualities: 1) architecturally significant (if implemented, we are forced to design, build, and test the core architecture), 2) high business value (features business really cares about), and 3) high risk (such as "be able to handle 500 concurrent transactions"). Perhaps three use cases are thus identified: UC2, UC11, UC14.

                                                                  • For the remaining 1.5 days, do intensive detailed analysis of the functional and non-functional requirements for these three use cases. When finished, 10% are deeply analyzed, and 90% are only high-level.

                                                                3. 在迭代 1 之前,召开迭代规划会议,从 UC2、UC11 和 UC14 中选择子集,在指定时间内进行设计、构建和测试(例如,为期 4 周的有时间限制的迭代)。请注意,并非所有这三个用例都可以在 iteration-1 中构建,因为它们将包含太多工作。选择特定的子集目标后,在开发团队的帮助下,将它们分解为一组更详细的迭代任务。

                                                                4. Before iteration-1, hold an iteration planning meeting in which a subset from UC2, UC11, and UC14 are chosen to design, build, and test within a specified time (for example, four-week timeboxed iteration). Note that not all of these three use cases can be built in iteration-1, as they will contain too much work. After choosing the specific subset goals, break them down into a set of more detailed iteration tasks, with help from the development team.

                                                                5. 在 3 到 4 周内进行迭代 1(选择时间盒,并坚持下去)。

                                                                  • 在前两天,开发人员和其他人两人一组进行建模和设计工作,在总架构师的指导和指导下,在许多白板上绘制类似 UML 的图表(以及绘制其他类型的模型)。

                                                                  • 然后,开发人员摘下他们的 “建模帽” ,戴上他们的 “编程帽”。他们在剩下的几周内不断开始编程、测试和集成他们的工作,以建模草图作为灵感的起点,因为他们知道这些模型是片面的,而且往往是模糊的。

                                                                  • 会进行很多测试:unit、acceptance、load、usability 等。

                                                                  • 在结束前一周,询问团队是否可以达到最初的迭代目标;如果没有,请缩小迭代的范围,将次要目标放回 “To do” 列表中。

                                                                  • 上周的星期二,代码冻结;必须签入、集成和测试所有代码才能创建迭代基线。

                                                                  • 在星期三上午,向外部利益相关者演示部分系统,以展示早期可见的进展。请求反馈。

                                                                6. Do iteration-1 over three or four weeks (pick the timebox, and stick to it).

                                                                  • On the first two days, developers and others do modeling and design work in pairs, sketching UML-ish diagrams at many whiteboards (along with sketching other kinds of models) in a common war room, coached and guided by the chief architect.

                                                                  • Then the developers take off their "modeling hats" and put on their "programming hats." They start programming, testing, and integrating their work continuously over the remaining weeks, using the modeling sketches as a starting point of inspiration, knowing that the models are partial and often vague.

                                                                  • Much testing occurs: unit, acceptance, load, usability, and so forth.

                                                                  • One week before the end, ask the team if the original iteration goals can be met; if not, de-scope the iteration, putting secondary goals back on the "to do" list.

                                                                  • On Tuesday of the last week there's a code freeze; all code must be checked in, integrated, and tested to create the iteration baseline.

                                                                  • On Wednesday morning, demo the partial system to external stakeholders, to show early visible progress. Feedback is requested.

                                                                7. 在迭代 1 接近尾声时进行第二次需求研讨会,例如在最后一个星期三和星期四。查看并完善上次研讨会的所有材料。然后选择另外 10% 或 15% 的架构重要且具有高业务价值的使用案例,并对其进行一两天的详细分析。完成后,可能会详细编写 25% 的用例和非功能性需求。他们不会完美。

                                                                8. Do the second requirements workshop near the end of iteration-1, such as on the last Wednesday and Thursday. Review and refine all the material from the last workshop. Then pick another 10% or 15% of the use cases that are architecturally significant and of high business value, and analyze them in detail for one or two days. When finished, perhaps 25% of the use cases and non-functional requirements will be written in detail. They won't be perfect.

                                                                9. 在星期五早上,为下一次迭代举行另一次迭代规划会议。

                                                                10. On Friday morning, hold another iteration planning meeting for the next iteration.

                                                                11. 执行迭代 2;类似的步骤。

                                                                12. Do iteration-2; similar steps.

                                                                13. 重复,对于 4 次迭代和 5 次需求研讨会,以便在迭代 4 结束时,可能已经详细编写了 80% 或 90% 的需求,但只有 10% 的系统已经实现。

                                                                  • 请注意,这组庞大而详细的需求是基于反馈和演变的,因此比纯粹的推测性瀑布规范质量要高得多。

                                                                14. Repeat, for four iterations and five requirements workshops, so that at the end of iteration-4, perhaps 80% or 90% of the requirements have been written in detail, but only 10% of the system has been implemented.

                                                                  • Note that this large, detailed set of requirements is based on feedback and evolution, and is thus of much higher quality than purely speculative waterfall specifications.

                                                                15. 我们可能只完成了整个项目持续时间的 20%。用 UP 术语来说,这是阐述阶段的结束。此时,请详细估计优化、高质量要求的工作量和时间。由于重要的现实调查、反馈以及早期编程和测试,因此对可以做什么以及需要多长时间的估计要可靠得多。

                                                                16. We are perhaps only 20% into the duration of the overall project. In UP terms, this is the end of the elaboration phase. At this point, estimate in detail the effort and time for the refined, high-quality requirements. Because of the significant realistic investigation, feedback, and early programming and testing, the estimates of what can be done and how long it will take are much more reliable.

                                                                17. 在此之后,需求研讨会不太可能;需求是稳定的,但从未完全冻结。继续进行一系列为期三周的迭代,在最后一个星期五的每次迭代计划会议上自适应地选择下一步工作,在每次迭代中重新提出问题,“根据我们今天所知道的,在接下来的三周内我们应该做的最关键的技术和业务功能是什么?

                                                                18. After this point, requirements workshops are unlikely; the requirements are stabilizedthough never completely frozen. Continue in a series of three-week iterations, choosing the next step of work adaptively in each iteration planning meeting on the final Friday, re-asking the question each iteration, "Given what we know today, what are the most critical technical and business features we should do in the next three weeks?"

                                                                图 2.5 说明了 20 次迭代项目的方法。

                                                                Figure 2.5 illustrates the approach for a 20-iteration project.

                                                                图 2.5.项目中序列图的 UML 草图。



                                                                通过这种方式,经过几次早期探索性开发迭代后,团队可以更可靠地回答 “什么、多少、何时”。

                                                                In this way, after a few iterations of early exploratory development, there comes a point when the team can more reliably answer "what, how much, when."

                                                                  2.5. 什么是风险驱动型迭代规划和客户驱动型迭代规划?

                                                                  2.5. What is Risk-Driven and Client-Driven Iterative Planning?

                                                                  UP(以及大多数新方法)鼓励风险驱动客户驱动的迭代规划相结合。这意味着早期迭代的目标被选择为 1) 识别并降低最高风险,以及 2) 构建客户最关心的可见功能。

                                                                  The UP (and most new methods) encourage a combination of risk-driven and client-driven iterative planning. This means that the goals of the early iterations are chosen to 1) identify and drive down the highest risks, and 2) build visible features that the client cares most about.

                                                                  风险驱动的迭代开发更具体地包括以架构为中心的迭代开发实践,这意味着早期迭代侧重于构建、测试和稳定核心架构。为什么?因为没有可靠的架构是一种常见的高风险。

                                                                  Risk-driven iterative development includes more specifically the practice of architecture-centric iterative development, meaning that early iterations focus on building, testing, and stabilizing the core architecture. Why? Because not having a solid architecture is a common high risk.

                                                                  书籍迭代与真实项目迭代

                                                                  Book Iterations vs. Real Project Iterations

                                                                  本书中案例研究的迭代 1 是由学习目标而不是真正的项目目标驱动的。因此,迭代 1 不是以架构为中心或风险驱动的。在实际项目中,我们会首先处理困难和风险的事情。但是在一本帮助人们学习基本 OOA/D 和 UML 的书的上下文中,这是不切实际的我们需要从说明基本原则的问题开始,而不是最困难的主题和问题。

                                                                  Iteration-1 of the case studies in this book is driven by learning goals rather than true project goals. Therefore, iteration-1 is not architecture-centric or risk-driven. On a real project, we would tackle difficult and risky things first. But in the context of a book helping people learn fundamental OOA/D and UML, that's impracticalwe need to start with problems illustrating basic principles, not the most difficult topics and problems.



                                                                    2.6. 什么是敏捷方法和态度?

                                                                    2.6. What are Agile Methods and Attitudes?

                                                                    敏捷开发方法通常应用有时间限制的迭代和渐进式开发,采用适应性规划,促进增量交付,并包括其他价值和实践,鼓励敏捷、快速和灵活地响应变化。

                                                                    Agile development methods usually apply timeboxed iterative and evolutionary development, employ adaptive planning, promote incremental delivery, and include other values and practices that encourage agilityrapid and flexible response to change.

                                                                    图 2.4.进化分析和设计在早期迭代中占大多数。



                                                                    由于具体实践差异很大,因此无法准确定义敏捷方法。然而,具有计划、需求和设计的渐进式改进的短时间盒迭代是这些方法共享的基本实践。此外,它们还促进了反映简单、轻便、沟通、自组织团队等敏捷敏感性的实践和原则。

                                                                    It is not possible to exactly define agile methods, as specific practices vary widely. However, short timeboxed iterations with evolutionary refinement of plans, requirements, and design is a basic practice the methods share. In addition, they promote practices and principles that reflect an agile sensibility of simplicity, lightness, communication, self-organizing teams, and more.

                                                                    Scrum 敏捷方法的示例实践包括一个公共项目工作室自组织团队,这些团队通过每日站立会议进行协调,每个成员回答四个特殊问题。极限编程 (XP) 方法的示例实践包括成对编程和测试驱动开发

                                                                    Example practices from the Scrum agile method include a common project workroom and self-organizing teams that coordinate through a daily stand-up meeting with four special questions each member answers. Example practices from the Extreme Programming (XP) method include programming in pairs and test-driven development.

                                                                    TDD385

                                                                    TDD p. 385



                                                                    任何迭代方法,包括 UP,都可以本着敏捷的精神应用。UP 本身也很灵活,鼓励“只要有效”的态度,包括 Scrum、XP 和其他方法的实践。

                                                                    Any iterative method, including the UP, can be applied in an agile spirit. And the UP itself is flexible, encouraging a "whatever works" attitude to include practices from Scrum, XP, and other methods.

                                                                    敏捷宣言和原则

                                                                    The Agile Manifesto and Principles

                                                                    敏捷宣言

                                                                    个人和交互

                                                                    Individuals and interactions

                                                                    超越流程和工具

                                                                    over processes and tools

                                                                    工作软件

                                                                    Working software

                                                                    全面的文档

                                                                    over comprehensive documentation

                                                                    客户协作

                                                                    Customer collaboration

                                                                    合同谈判

                                                                    over contract negotiation

                                                                    响应变化

                                                                    Responding to change

                                                                    超过遵循计划

                                                                    over following a plan



                                                                    敏捷原则

                                                                    1. 我们的首要任务是通过尽早和持续交付有价值的软件来满足客户。

                                                                    1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.

                                                                    8. 敏捷流程促进可持续发展。

                                                                    8. Agile processes promote sustainable development.

                                                                    2. 欢迎不断变化的需求,即使是在开发后期。敏捷流程利用变化来获得客户的竞争优势。

                                                                    2. Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.

                                                                    9. 赞助商、开发者和用户应该能够无限期地保持恒定的步伐。

                                                                    9. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.

                                                                    3. 经常交付工作软件,从几周到几个月不等,优先考虑较短的时间尺度。

                                                                    3. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter time scale.

                                                                    10. 持续关注技术卓越和良好设计可以提高敏捷性。

                                                                    10. Continuous attention to technical excellence and good design enhances agility.

                                                                    4. 业务人员和开发人员必须在整个项目中每天一起工作。

                                                                    4. Business people and developers must work together daily throughout the project.

                                                                    11. 简单最大化未完成的工作量的艺术是必不可少的。

                                                                    11. Simplicitythe art of maximizing the amount of work not doneis essential.

                                                                    5. 围绕积极进取的个人构建项目。为他们提供所需的环境和支持,并相信他们能够完成工作。

                                                                    5. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.

                                                                    12. 最好的架构、需求和设计来自自组织团队。

                                                                    12. The best architectures, requirements, and designs emerge from self-organizing teams.

                                                                    6. 向开发团队和在开发团队内部传达信息的最有效方法是面对面的对话。

                                                                    6. The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.

                                                                    13. 团队会定期反思如何变得更有效,然后相应地调整和调整其行为。

                                                                    13. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.

                                                                    7. 工作软件是衡量进步的主要标准。

                                                                    7. Working software is the primary measure of progress.

                                                                     



                                                                    2001 年,一个对迭代和敏捷方法(创造了这个词)感兴趣的小组开会寻找共同点。由此诞生了敏捷联盟 (www.agilealliance.com),它提出了一个宣言和原则声明,以捕捉敏捷方法的精神。

                                                                    In 2001 agroup interested in iterative and agile methods (coining the term) met to find common ground. Out of this came the Agile Alliance (www.agilealliance.com) with a manifesto and statement of principles to capture the spirit of agile methods.

                                                                      2.7. 什么是敏捷建模?

                                                                      2.7. What is Agile Modeling?

                                                                      经验丰富的分析师和建模师都知道建模的秘诀

                                                                      Experienced analysts and modelers know the secret of modeling:

                                                                      建模(草绘 UML 等)的目的主要是理解,而不是记录。

                                                                      The purpose of modeling (sketching UML, …) is primarily to understand, not to document.



                                                                      也就是说,建模行为本身可以而且应该提供一种方法来更好地理解问题或解决方案空间。从这个角度来看,“做 UML”(这实际上应该意味着“做 OOA/D”)的目的不是让设计师创建许多详细的 UML 图,然后交给程序员(这是一种非常不敏捷和瀑布导向的思维方式),而是快速探索(比使用代码更快)替代方案和通往良好 OO 设计的途径。

                                                                      That is, the very act of modeling can and should provide a way to better understand the problem or solution space. From this viewpoint, the purpose of "doing UML" (which should really mean "doing OOA/D") is not for a designer to create many detailed UML diagrams that are handed off to a programmer (which is a very un-agile and waterfall-oriented mindset), but rather to quickly explore (more quickly than with code) alternatives and the path to a good OO design.

                                                                      这种观点与敏捷方法一致,在《敏捷建模》一书 [Ambler02] 中被称为敏捷建模。它意味着许多实践和价值观,包括:

                                                                      This view, consistent with agile methods, has been called agile modeling in the book (amazingly called) Agile Modeling [Ambler02]. It implies a number of practices and values, including:

                                                                      • 采用敏捷方法并不意味着避免任何建模;这是一个误解。许多敏捷方法(例如功能驱动开发、DSDM 和 Scrum)通常包括重要的建模会话。即使是 XP 的创始人,也许是最著名的敏捷方法,但对建模的重视程度最低,也赞同 Amblerand 所描述的敏捷建模,多年来许多建模者都在实践这种敏捷建模。

                                                                      • Adopting an agile method does not mean avoiding any modeling; that's a misunderstanding. Many agile methods, such as Feature-Driven Development, DSDM, and Scrum, normally include significant modeling sessions. Even the XP founders, from perhaps the most well-known agile method with the least emphasis on modeling, endorsed agile modeling as described by Amblerand practiced by many modelers over the years.

                                                                      • 建模和模型的目的主要是支持理解和交流,而不是文档。

                                                                      • The purpose of modeling and models is primarily to support understanding and communication, not documentation.

                                                                      • 不要将 UML 建模或应用于所有或大部分软件设计。将简单或直接的设计问题推迟到编程解决它们时,同时进行编程和测试。对设计空间中较小比例的不常见、困难、棘手的部分进行建模和应用 UML。

                                                                      • Don't model or apply the UML to all or most of the software design. Defer simple or straightforward design problems until programmingsolve them while programming and testing. Model and apply the UML for the smaller percentage of unusual, difficult, tricky parts of the design space.

                                                                      • 使用最简单的工具。更喜欢支持快速输入和更改的“低能耗”创造力增强简单工具。此外,选择支持大型视觉空间的工具。例如,更喜欢在白板上绘制 UML 草图,并使用数码相机捕获图表。[2]

                                                                        [2] 两个白板素描技巧::如果你没有足够的白板(你应该有很多大白板),另一种选择是“白板”塑料粘附板,它粘在墙上(带静电)以制作白板。北美的主要产品是 Avery Write-On 保鲜纸;欧洲的主要产品是 LegaMaster Magic-Chart。第二:白板图像的数码照片通常很差(由于反射)。不要使用闪光灯,但如果您需要清理图像,请使用软件“白板图像清理”应用程序来改进图像(就像我为这本书所做的那样)。

                                                                        • 这并不意味着 UML CASE 工具或文字处理器不能使用或没有价值,但特别是对于发现的创造性工作,在白板上绘制草图支持快速的创意流程和变化。无论采用何种技术,关键规则是易用性和敏捷性。

                                                                      • Use the simplest tool possible. Prefer "low energy" creativity-enhancing simple tools that support rapid input and change. Also, choose tools that support large visual spaces. For example, prefer sketching UML on whiteboards, and capturing the diagrams with a digital camera.[2]

                                                                        [2] Two whiteboard sketching tips: One: If you don't have enough whiteboards (and you should have many large ones), an alternative is "whiteboard" plastic cling sheets which cling to walls (with a static charge) to create whiteboards. The main product in North America is Avery Write-On Cling Sheets; the main product in Europe is LegaMaster Magic-Chart. Two: Digital photos of whiteboard images are often poor (due to reflection). Don't use a flash, but use a software "whiteboard image clean up" application to improve the images, if you need to clean them (as I did for this book).

                                                                        • This doesn't mean UML CASE tools or word processors can't be used or have no value, but especially for the creative work of discovery, sketching on whiteboards supports quick creative flow and change. The key rule is ease and agility, whatever the technology.

                                                                      • 不要单独建模,而是在白板上成对(或三合会)建模,因为要意识到建模的目的是发现、理解和分享这种理解。在杆件之间旋转钢笔草绘,以便所有杆件都参与。

                                                                      • Don't model alone, model in pairs (or triads) at the whiteboard, in the awareness that the purpose of modeling is to discover, understand, and share that understanding. Rotate the pen sketching across the members so that all participate.

                                                                      • 并行创建模型。例如,在一个白板上开始绘制动态视图 UML 交互图,在另一个白板上开始绘制互补的静态视图 UML 类图。一起开发两个模型(两个视图),来回切换。

                                                                      • Create models in parallel. For example, on one whiteboard start sketching a dynamic-view UML interaction diagram, and on another whiteboard, start sketching the complementary static-view UML class diagram. Develop the two models (two views) together, switching back and forth.

                                                                      • 使用“足够好”的简单符号,同时用笔在白板上画草图。确切的 UML 细节并不重要,只要建模者彼此理解即可。坚持使用简单、常用的 UML 元素。

                                                                      • Use "good enough" simple notation while sketching with a pen on whiteboards. Exact UML details aren't important, as long as the modelers understand each other. Stick to simple, frequently used UML elements.

                                                                      • 要知道,所有模型都是不准确的,最终的代码或设计也会有所不同,有时与模型截然不同。只有经过测试的代码才能证明真正的设计;所有前面的图表都是不完整的提示,最好轻描淡写地视为一次性探索。

                                                                      • Know that all models will be inaccurate, and the final code or design differentsometimes dramatically differentthan the model. Only tested code demonstrates the true design; all prior diagrams are incomplete hints, best treated lightly as throw-away explorations.

                                                                      • 开发人员自己应该自己做 OO 设计建模,而不是创建图表,然后交给其他程序员来实现非敏捷的面向瀑布的实践示例。

                                                                      • Developers themselves should do the OO design modeling, for themselves, not to create diagrams that are given to other programmers to implementan example of un-agile waterfall-oriented practices.

                                                                      本书中的敏捷建模:为什么是 UML 草图的快照?

                                                                      Agile Modeling in this Book: Why the Snapshots of UML Sketches?

                                                                      在白板上进行 UML 草图建模是一种实践,许多开发人员多年来一直热情地指导和实践。然而,本书中的大多数 UML 图都给人的印象是我不是这样工作的,因为它们是用工具整齐地绘制的,以提高可读性。为了平衡这种印象,这本书偶尔会包括白板 UML 草图的数字快照图片。它牺牲了易读性,但提醒了敏捷建模是有用的,并且是案例研究背后的实际实践。

                                                                      UML-sketch modeling on whiteboards is a practice Iand many developershave enthusiastically coached and practiced for years. Yet most of the UML diagrams in this book give the impression I don't work that way, because they've been drawn neatly with a tool, for readability. To balance that impression the book occasionally includes digital snapshot pictures of whiteboard UML sketches. It sacrifices legibility but reminds that agile modeling is useful and is the actual practice behind the case studies.

                                                                      例如,图 2.5 是在我指导的一个项目上创建的未经编辑的 UML 草图。画画花了大约 20 分钟,周围站着四名开发人员。我们需要了解系统间的协作。将其整合在一起的行为为贡献独特的见解并达成共识提供了一个环境。这捕捉到了敏捷建模者如何应用 UML 的感觉。

                                                                      For example, Figure 2.5 is an unedited UML sketch created on a project I was coaching. It took about 20 minutes to draw, with four developers standing around. We needed to understand the inter-system collaboration. The act of drawing it together provided a context to contribute unique insights and reach shared understanding. This captures the feel of how agile modelers apply the UML.

                                                                        2.8. 什么是 Agile UP?

                                                                        2.8. What is an Agile UP?

                                                                        UP 的创建者并不是说它是沉重或不敏捷的,尽管它大量的可选活动和工件导致了一些人留下这种印象,这是可以理解的。相反,它本着适应性和轻便敏捷 UP 的精神被采用和应用。具体应用方式的一些示例:

                                                                        The UP was not meant by its creators to be heavy or un-agile, although its large optional set of activities and artifacts have understandably led some to that impression. Rather, it was meant to be adopted and applied in the spirit of adaptability and lightnessan agile UP. Some examples of how this applies:

                                                                        • 首选一小部分 UP 活动和工件。有些项目会比其他项目受益更多,但总的来说,请保持简单。请记住,所有 UP 工件都是可选的,除非它们能增加价值,否则请避免创建它们。专注于早期编程,而不是早期记录。

                                                                          定制 UP,第 37



                                                                        • Prefer a small set of UP activities and artifacts. Some projects will benefit more than others, but, in general, keep it simple. Remember that all UP artifacts are optional, and avoid creating them unless they add value. Focus on early programming, not early documenting.



                                                                        • 由于 UP 是迭代和进化的,因此在实施之前不会完成需求和设计。它们根据反馈通过一系列迭代自适应地出现。

                                                                          进化论 A&D25



                                                                        • Since the UP is iterative and evolutionary, requirements and designs are not completed before implementation. They adaptively emerge through a series of iterations, based on feedback.



                                                                        • 将 UML 与敏捷建模实践一起应用。

                                                                          敏捷模型30



                                                                        • Apply the UML with agile modeling practices.



                                                                        • 整个项目没有详细的计划。有一个高级计划(称为阶段计划)来估计项目结束日期和其他主要里程碑,但它没有详细说明这些里程碑的细粒度步骤。详细计划(称为 Iteration Plan)仅提前一个迭代进行更详细的计划。详细规划在迭代之间自适应地完成。

                                                                        • There isn't a detailed plan for the entire project. There is a high-level plan (called the Phase Plan) that estimates the project end date and other major milestones, but it does not detail the fine-grained steps to those milestones. A detailed plan (called the Iteration Plan) only plans with greater detail one iteration in advance. Detailed planning is done adaptively from iteration to iteration.



                                                                        案例研究强调相对较少的工件和迭代开发,本着敏捷 UP 的精神。

                                                                        The case studies emphasize a relatively small number of artifacts, and iterative development, in the spirit of an agile UP.

                                                                          2.9. 还有其他关键的 UP 实践吗?

                                                                          2.9. Are There Other Critical UP Practices?

                                                                          在 UP 中欣赏和实践的中心思想是短时间盒迭代、进化和适应性发展。UP 中的其他一些最佳实践和关键概念:

                                                                          The central idea to appreciate and practice in the UP is short timeboxed iterative, evolutionary, and adaptive development. Some additional best practices and key concepts in the UP:

                                                                          • 在早期迭代中解决高风险和高价值问题

                                                                          • tackle high-risk and high-value issues in early iterations

                                                                          • 持续吸引用户进行评估、反馈和要求

                                                                          • continuously engage users for evaluation, feedback, and requirements

                                                                          • 在早期迭代中构建一个有凝聚力的核心架构

                                                                          • build a cohesive, core architecture in early iterations

                                                                          • 持续验证质量;尽早、经常、切合实际地进行测试

                                                                          • continuously verify quality; test early, often, and realistically

                                                                          • 在适当的情况下应用用例

                                                                          • apply use cases where appropriate

                                                                          • 做一些可视化建模(使用 UML)

                                                                          • do some visual modeling (with the UML)

                                                                          • 仔细管理需求

                                                                          • carefully manage requirements

                                                                          • 练习更改请求和配置管理

                                                                          • practice change request and configuration management

                                                                            2.10. 什么是 UP 阶段?

                                                                            2.10. What are the UP Phases?

                                                                            UP 项目将工作和迭代组织为四个主要阶段:

                                                                            A UP project organizes the work and iterations across four major phases:

                                                                            1. 初始大致愿景、商业案例、范围、模糊估计。

                                                                            2. Inception approximate vision, business case, scope, vague estimates.

                                                                            3. 细化细化的愿景,迭代实现核心架构,解决高风险,确定大多数需求和范围,更现实的估计。

                                                                            4. Elaboration refined vision, iterative implementation of the core architecture, resolution of high risks, identification of most requirements and scope, more realistic estimates.

                                                                            5. 构建迭代实施剩余的 lower risk 和 easier 元素,并为部署做准备。

                                                                            6. Construction iterative implementation of the remaining lower risk and easier elements, and preparation for deployment.

                                                                            7. 过渡 beta 测试、部署。

                                                                            8. Transition beta tests, deployment.

                                                                            这些阶段在后续章节中有更完整的定义。

                                                                            These phases are more fully defined in subsequent chapters.

                                                                            这不是旧的 “瀑布” 或顺序生命周期,即首先定义所有需求,然后执行所有或大部分设计。

                                                                            This is not the old "waterfall" or sequential lifecycle of first defining all the requirements, and then doing all or most of the design.

                                                                            Inception 不是一个需求阶段;相反,这是一个可行性阶段,在这个阶段,所做的调查刚刚好足以支持继续或停止的决定。

                                                                            Inception is not a requirements phase; rather, it is a feasibility phase, where just enough investigation is done to support a decision to continue or stop.

                                                                            同样,细化不是需求或设计阶段;相反,这是一个迭代实现核心架构并缓解高风险问题的阶段。

                                                                            Similarly, elaboration is not the requirements or design phase; rather, it is a phase where the core architecture is iteratively implemented, and high-risk issues are mitigated.

                                                                            图 2.6 说明了 UP 中常见的面向进度的术语。请注意,一个开发周期(以系统发布到生产环境结束)由许多迭代组成。

                                                                            Figure 2.6 illustrates common schedule-oriented terms in the UP. Notice that one development cycle (which ends in the release of a system into production) is composed of many iterations.

                                                                            图 2.6.Schedule-oriented terms in the UP.



                                                                              2.11. 什么是 UP 学科?

                                                                              2.11. What are the UP Disciplines?

                                                                              UP 描述了学科内的工作活动(例如编写用例)一个主题领域的一组活动(和相关工件),例如需求分析中的活动。在 UP 中,工件是任何工作产品的通用术语:代码、Web 图形、数据库架构、文本文档、图表、模型等。

                                                                              The UP describes work activities, such as writing a use case, within disciplinesa set of activities (and related artifacts) in one subject area, such as the activities within requirements analysis. In the UP, an artifact is the general term for any work product: code, Web graphics, database schema, text documents, diagrams, models, and so on.

                                                                              UP 有几个学科;本书重点介绍以下三个方面的一些工件:

                                                                              There are several disciplines in the UP; this book focuses on some artifacts in the following three:

                                                                              • 业务建模Domain Model 工件,用于可视化应用程序域中值得注意的概念。

                                                                              • Business Modeling The Domain Model artifact, to visualize noteworthy concepts in the application domain.

                                                                              • 要求用于捕获功能和非功能需求的 Use-Case Model 和 Supplementary Specification 工件。

                                                                              • Requirements The Use-Case Model and Supplementary Specification artifacts to capture functional and non-functional requirements.

                                                                              • 设计Design Model 工件,用于设计软件对象。

                                                                              • Design The Design Model artifact, to design the software objects.

                                                                              图 2.7 显示了一个更长的 UP 学科列表。

                                                                              A longer list of UP disciplines is shown in Figure 2.7.

                                                                              图 2.7.UP 学科。



                                                                              在 UP 中,实现意味着对系统进行编程和构建,而不是部署它。环境学科是指为项目建立工具和自定义过程,即设置工具和过程环境。

                                                                              In the UP, Implementation means programming and building the system, not deploying it. The Environment discipline refers to establishing the tools and customizing the process for the projectthat is, setting up the tool and process environment.

                                                                              学科和阶段之间的关系是什么?

                                                                              What is the Relationship Between the Disciplines and Phases?

                                                                              如图 2.7 所示,在一次迭代期间,大多数或所有学科的工作都在进行。但是,这些学科的相对工作量会随着时间的推移而变化。早期迭代自然倾向于相对强调需求和设计,而后期迭代则不那么重要,因为需求和核心设计通过反馈和适应过程稳定下来。

                                                                              As illustrated in Figure 2.7, during one iteration work goes on in most or all disciplines. However, the relative effort across these disciplines changes over time. Early iterations naturally tend to apply greater relative emphasis to requirements and design, and later ones less so, as the requirements and core design stabilize through a process of feedback and adaptation.

                                                                              将此与 UP 阶段(开始、阐述等)联系起来,图 2.8 说明了相对于各个阶段不断变化的相对努力;请注意,这些是暗示性的,而不是字面意思。例如,在细化方面,迭代往往具有相对较高的需求和设计工作水平,尽管肯定也有一些实现。在施工过程中,重点更重于实施,而轻重于需求分析。

                                                                              Relating this to the UP phases (inception, elaboration, …), Figure 2.8 illustrates the changing relative effort with respect to the phases; please note these are suggestive, not literal. In elaboration, for example, the iterations tend to have a relatively high level of requirements and design work, although definitely some implementation as well. During construction, the emphasis is heavier on implementation and lighter on requirements analysis.

                                                                              图 2.8.学科和阶段。



                                                                              书籍结构如何受到 UP 阶段和学科的影响?

                                                                              How is the Book Structure Influenced by UP Phases and Disciplines?

                                                                              关于阶段和学科,案例研究的重点是什么?

                                                                              With respect to the phases and disciplines, what is the focus of the case studies?

                                                                              案例研究强调开始和阐述阶段。他们专注于业务建模、需求和设计学科中的一些工件,因为这是需求分析、OOA/D、模式和 UML 的主要应用位置。

                                                                              The case studies emphasize the inception and elaboration phase. They focus on some artifacts in the Business Modeling, Requirements, and Design disciplines, as this is where requirements analysis, OOA/D, patterns, and the UML are primarily applied.



                                                                              前面的章节介绍了 inception 中的活动;后面的章节探讨了阐述中的几次迭代。以下列表和图 2.9 描述了组织在 UP 阶段方面的表现。

                                                                              The earlier chapters introduce activities in inception; later chapters explore several iterations in elaboration. The following list and Figure 2.9 describe the organization with respect to the UP phases.

                                                                              1. 初始阶段章节介绍了需求分析的基础知识。

                                                                              2. The inception phase chapters introduce the basics of requirements analysis.

                                                                              3. 迭代 1 引入了基本的 OOA/D 和对象的责任分配。

                                                                              4. Iteration 1 introduces fundamental OOA/D and assignment of responsibilities to objects.

                                                                              5. 迭代 2 侧重于对象设计,特别是引入一些使用率较高的 “设计模式”。

                                                                              6. Iteration 2 focuses on object design, especially on introducing some high-use "design patterns."

                                                                              7. 迭代 3 引入了各种主题,例如架构分析和框架设计。

                                                                              8. Iteration 3 introduces a variety of subjects, such as architectural analysis and framework design.

                                                                              图 2.9.书籍组织与 UP 阶段和迭代相关。



                                                                                2.12. 如何自定义流程?UP 开发案例

                                                                                2.12. How to Customize the Process? The UP Development Case

                                                                                UP 中是否有可选的工件或实践?

                                                                                Are There Optional Artifacts or Practices in the UP?

                                                                                是的!几乎所有内容都是可选的。也就是说,一些 UP 实践和原则是不变的,例如迭代和风险驱动的开发,以及对质量的持续验证。

                                                                                Yes! Almost everything is optional. That said, some UP practices and principles are invariant, such as iterative and risk-driven development, and continuous verification of quality.

                                                                                然而,对 UP 的一个关键见解是,所有活动和工件(模型、图表、文档等)都是可选的,也许不是代码!

                                                                                However, a key insight into the UP is that all activities and artifacts (models, diagrams, documents, …) are optionalwell, maybe not the code!

                                                                                类比

                                                                                Analogy

                                                                                UP 中描述的一组可能的伪影应该被视为药房中的一组药物。就像一个人不会不加选择地服用许多药物,而是将选择与疾病相匹配一样,在 UP 项目中,团队应该选择一小部分工件来解决其特定问题和需求。一般来说,请专注于一小部分具有高实用价值的工件。

                                                                                The set of possible artifacts described in the UP should be viewed like a set of medicines in a pharmacy. Just as one does not indiscriminately take many medicines, but matches the choice to the ailment, likewise on a UP project, a team should select a small subset of artifacts that address its particular problems and needs. In general, focus on a small set of artifacts that demonstrate high practical value.



                                                                                定义:什么是开发案例?

                                                                                Definition: What is the Development Case?

                                                                                项目的实践和 UP 工件的选择可以写在一个名为 Development Case 的简短文档(环境学科中的工件)中。例如,表 2.1 可能是本书中探讨的“NextGen Project”案例研究的开发案例。

                                                                                The choice of practices and UP artifacts for a project may be written up in a short document called the Development Case (an artifact in the Environment discipline). For example, Table 2.1 could be the Development Case for the "NextGen Project" case study explored in this book.

                                                                                表 2.1.示例开发案例。s - 开始;R - 优化

                                                                                学科

                                                                                Discipline

                                                                                实践

                                                                                Practice

                                                                                人工制品

                                                                                Artifact

                                                                                因塞普。

                                                                                Incep.

                                                                                埃拉布。

                                                                                Elab.

                                                                                常量。

                                                                                Const.

                                                                                反式。

                                                                                Trans.

                                                                                迭 代

                                                                                Iteration

                                                                                I1

                                                                                E1..中文

                                                                                E1..En

                                                                                C1..快递 之 家

                                                                                C1..Cn

                                                                                T1..T2 航站楼

                                                                                T1..T2

                                                                                业务建模

                                                                                Business Modeling

                                                                                敏捷建模要求研讨会

                                                                                agile modeling req. workshop

                                                                                域模型

                                                                                Domain Model

                                                                                 

                                                                                s

                                                                                s

                                                                                  

                                                                                要求

                                                                                Requirements

                                                                                req. 研讨会 Vision Box 练习 DOT 投票

                                                                                req. workshop vision box exercise dot voting

                                                                                用例模型

                                                                                Use-Case Model

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                  

                                                                                视觉

                                                                                Vision

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                  

                                                                                补充规格

                                                                                Supplementary Specification

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                  

                                                                                词汇表

                                                                                Glossary

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                  

                                                                                设计

                                                                                Design

                                                                                敏捷建模 测试驱动型开发

                                                                                agile modeling test-driven dev.

                                                                                设计模型

                                                                                Design Model

                                                                                 

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                 

                                                                                软件架构文档

                                                                                SW Architecture Document

                                                                                 

                                                                                s

                                                                                s

                                                                                  

                                                                                数据模型

                                                                                Data Model

                                                                                 

                                                                                s

                                                                                s

                                                                                r

                                                                                r

                                                                                 

                                                                                实现

                                                                                Implementation

                                                                                测试驱动型开发结对编程 持续集成 编码标准

                                                                                test-driven dev. pair programming continuous integration coding standards

                                                                                    

                                                                                项目管理

                                                                                Project Management

                                                                                敏捷 PM 每日 Scrum 会议

                                                                                agile PM daily Scrum meeting

                                                                                    

                                                                                      



                                                                                后续章节描述了其中一些工件的创建,包括 Domain Model、Use-Case Model 和 Design Model。

                                                                                Subsequent chapters describe the creation of some of these artifacts, including the Domain Model, Use-Case Model, and Design Model.

                                                                                本案例研究中介绍的示例实践和工件绝不足以或适合所有项目。例如,机器控制系统可能会从许多状态图中受益。基于 Web 的电子商务系统可能需要关注用户界面原型。“绿地”新开发项目与系统集成项目具有截然不同的设计工件需求。

                                                                                The example practices and artifacts presented in this case study are by no means sufficient for, or suitable for, all projects. For example, a machine control system may benefit from many state diagrams. A Web-based e-commerce system may require a focus on user interface prototypes. A "green-field" new development project has very different design artifact needs than a systems integration project.

                                                                                  2.13. 你知道你不理解迭代开发或 UP,当时......

                                                                                  2.13. You Know You Didn't Understand Iterative Development or the UP When...

                                                                                  以下是一些迹象,表明您不理解以健康的敏捷精神采用迭代开发和 UP 意味着什么。

                                                                                  Here are some signs that you have not understood what it means to adopt iterative development and the UP in a healthy agile spirit.

                                                                                  • 在开始设计或实现之前,您尝试定义大多数需求。同样,在开始实现之前,您尝试定义大部分设计;在迭代编程和测试之前,您尝试完全定义并提交到架构中。

                                                                                  • You try to define most of the requirements before starting design or implementation. Similarly, you try to define most of the design before starting implementation; you try to fully define and commit to an architecture before iterative programming and testing.

                                                                                  • 在编程之前,您花了几天或几周的时间进行 UML 建模,或者您认为 UML 图表和设计活动是全面准确地详细定义设计和模型的时候。您将编程视为将这些代码的简单机械转换。

                                                                                  • You spend days or weeks in UML modeling before programming, or you think UML diagramming and design activities are a time to fully and accurately define designs and models in great detail. And you regard programming as a simple mechanical translation of these into code.

                                                                                  • 您认为 inception = requirements,elaboration = design,construction = implementation(即,将瀑布叠加在 UP 上)。

                                                                                  • You think that inception = requirements, elaboration = design, and construction = implementation (that is, superimposing the waterfall on the UP).

                                                                                  • 您认为细化的目的是全面、仔细地定义模型,并在构建过程中将其转换为代码。

                                                                                  • You think that the purpose of elaboration is to fully and carefully define models, which are translated into code during construction.

                                                                                  • 您认为合适的迭代长度是三个月,而不是三周。

                                                                                  • You believe that a suitable iteration length is three months long, rather than three weeks long.

                                                                                  • 您认为采用 UP 意味着要进行许多可能的活动并创建许多文档,并且您认为或体验 UP 是一个正式的、繁琐的过程,需要遵循许多步骤。

                                                                                  • You think that adopting the UP means to do many of the possible activities and create many documents, and you think of or experience the UP as a formal, fussy process with many steps to be followed.

                                                                                  • 您尝试从头到尾详细规划一个项目;您尝试推测性地预测所有迭代,以及每个迭代中会发生什么。

                                                                                  • You try to plan a project in detail from start to finish; you try to speculatively predict all the iterations, and what should happen in each one.

                                                                                    2.14. 历史

                                                                                    2.14. History

                                                                                    有关完整的故事和引文,请参阅“迭代和增量开发:简史”(IEEE Computer,2003 年 6 月,Larman 和 Basili),以及 [Larman03]。迭代方法的历史比许多人意识到的要久远。在 1950 年代后期,进化、迭代和增量开发 (IID),而不是瀑布式,被应用于水星太空项目,在 1960 年代初期,除了许多其他大型系统外,还应用于三叉戟潜艇项目。1968 年,IBM T.J. Watson 研究中心发表了第一篇促进迭代开发而不是瀑布式开发的论文。

                                                                                    For the full story and citations, see "Iterative and Incremental Development: A Brief History" (IEEE Computer, June 2003, Larman and Basili), and also [Larman03]. Iterative methods go back farther than many realize. In the late 1950s, evolutionary, iterative, and incremental development (IID), rather than the waterfall, was applied on the Mercury space project, and in the early 1960s, on the Trident submarine project, in addition to many other large systems. The first published paper promoting iterative rather than waterfall development was published in 1968 at the IBM T.J. Watson Research Center.

                                                                                    IID 在 1970 年代被用于许多大型国防和航空航天项目,包括美国航天飞机飞行控制软件(内置 17 次迭代,平均每次约 4 周)。1970 年代占主导地位的软件工程思想领袖 Harlan Mills 当时写了关于软件项目瀑布式的失败以及 IID 的必要性。私人顾问 Tom Gilb 在 1970 年代创建并发布了 IID Evo 方法,可以说是第一个完全成型的迭代方法。美国国防部在 1970 年代末和 1980 年代初采用了瀑布式标准 (DoD-2167);到 1980 年代后期,他们经历了重大失败(估计至少 50% 的软件项目被取消或无法使用),因此它被放弃,并最终(从 1987 年开始)被 IID 方法标准取代尽管瀑布影响的遗留问题仍然使一些 DoD 项目感到困惑。

                                                                                    IID was used on many large defense and aerospace projects in the 1970s, including the USA Space Shuttle flight control software (built in 17 iterations averaging about four weeks each). A dominant software engineering thought-leader of the 1970s, Harlan Mills, wrote at that time about the failure of the waterfall for software projects, and the need for IID. Tom Gilb, a private consultant, created and published the IID Evo method in the 1970s, arguably the first fully-formed iterative method. The USA Department of Defense had adopted a waterfall standard in the late 1970s and early 1980s (DoD-2167); by the late 1980s they were experiencing significant failure (estimates of at least 50% of software projects cancelled or unusable), and so it was dropped, and eventually (starting in 1987) replaced by IID method standardsalthough the legacy of waterfall influence still confuses some DoD projects.

                                                                                    同样在 1980 年代,那个年代的主要软件工程思想领袖 Frederick Brooks 博士(以 Mythical Man-Month 闻名)撰写并谈到了瀑布式的缺点以及改用 IID 方法的必要性。1980 年代的另一个里程碑是 Barry Boehm 博士发表了螺旋模型风险驱动的 IID 方法,他指出应用瀑布式时失败的风险很高。

                                                                                    Also in the 1980s, Dr. Frederick Brooks (of Mythical Man-Month fame), a major software engineering thoughtleader of that decade, wrote and spoke about the shortcomings of the waterfall and the need to instead use IID methods. Another 1980s milestone was the publication of the spiral model risk-driven IID method by Dr. Barry Boehm, citing the high risk of failure when the waterfall was applied.

                                                                                    到 1990 年代初期,IID 被广泛认为是瀑布式的继任者,迭代和进化方法如雨后春笋般涌现:UP、DSDM、Scrum、XP 等等。

                                                                                    By the early 1990s, IID was widely recognized as the successor to the waterfall, and there was a flowering of iterative and evolutionary methods: UP, DSDM, Scrum, XP, and many more.

                                                                                      2.15. 推荐资源

                                                                                      2.15. Recommended Resources

                                                                                      对 UP 及其在 RUP 中的改进的可读介绍是 Philippe Kruchten 的 The Rational Unified ProcessAn Introduction。Kruchten 和 Kroll 合著的 The Rational Unified Process Made Easy 也非常出色。

                                                                                      A readable introduction to the UP and its refinement in the RUP is The Rational Unified ProcessAn Introduction by Philippe Kruchten. Also excellent is The Rational Unified Process Made Easy, by Kruchten and Kroll.

                                                                                      敏捷和迭代开发:经理指南 [Larman03] 讨论了迭代和敏捷实践、四种迭代方法(XP、UP、Scrum 和 Evo)、它们背后的证据和历史,以及瀑布失败的证据。

                                                                                      Agile and Iterative Development: A Manager's Guide [Larman03] discusses iterative and agile practices, four iterative methods (XP, UP, Scrum, and Evo), the evidence and history behind them, and the evidence of failure for the waterfall.

                                                                                      对于其他迭代和敏捷方法,推荐使用极限编程 (XP) 系列书籍 [Beck00BF00JAH00],例如 Extreme Programming Explained。本书后面的章节鼓励进行一些 XP 练习。大多数 XP 实践(例如测试驱动编程、持续集成和迭代开发)与 UP 实践兼容或相同,我鼓励在 UP 项目中采用它们。

                                                                                      For other iterative and agile methods, the Extreme Programming (XP) series of books [Beck00, BF00, JAH00] are recommended, such as Extreme Programming Explained. Some XP practices are encouraged in later chapters of this book. Most XP practices (such as test-driven programming, continuous integration, and iterative development) are compatible withor identical toUP practices, and I encourage their adoption on a UP project.

                                                                                      Scrum 方法是另一种流行的迭代方法,它应用 30 天的有时间限制的迭代,每天召开站立会议,每个团队成员回答三个特殊问题。推荐阅读 Agile Software Development with Scrum

                                                                                      The Scrum method is another popular iterative approach that applies 30-day timeboxed iterations, with a daily stand-up meeting with three special questions answered by each team member. Agile Software Development with Scrum is recommended reading.

                                                                                      Scott Ambler 在 Agile Modeling 中介绍了敏捷建模。

                                                                                      Agile Modeling is described in Agile Modeling, by Scott Ambler.

                                                                                      IBM 销售基于 Web 的在线 RUP 文档产品,该产品提供有关 RUP 工件和活动的全面阅读,以及大多数工件的模板。一个组织可以只使用导师和书籍作为学习资源来运行 UP 项目,但有些人发现 RUP 产品是一种有用的学习和过程辅助工具。

                                                                                      IBM sells the online Web-based RUP documentation product, which provides comprehensive reading on RUP artifacts and activities, and templates for most artifacts. An organization can run a UP project just using mentors and books as learning resources, but some find the RUP product a useful learning and process aid.

                                                                                      对于 Web 资源:

                                                                                      For Web resources:

                                                                                      • www.agilealliance.com收集了许多专门与迭代和敏捷方法相关的文章,以及链接。

                                                                                      • www.agilealliance.com Collects many articles specifically related to iterative and agile methods, plus links.

                                                                                      • www.agilemodeling.com关于敏捷建模的文章。

                                                                                      • www.agilemodeling.com Articles on agile modeling.

                                                                                      • www.cetus-links.orgCetus Links 网站多年来一直专注于对象技术 (OT)。在“OO 项目管理OOA/D 方法”下,它有许多指向迭代和敏捷方法的链接,即使它们与 OT 没有直接关系。

                                                                                      • www.cetus-links.org The Cetus Links site has specialized for years in object technology (OT). Under "OO Project ManagementOOA/D Methods" it has many links to iterative and agile methods, even though they are not directly related to OT.

                                                                                      • www.bradapp.netBrad Appleton 维护着大量有关软件工程的链接,包括迭代方法。

                                                                                      • www.bradapp.net Brad Appleton maintains a large collection of links on software engineering, including iterative methods.

                                                                                      • www.iturls.com中文首页链接到英文版本,搜索引擎引用迭代和敏捷文章。

                                                                                      • www.iturls.com The Chinese front page links to an English version, with a search engine referencing iterative and agile articles.

                                                                                        第 3 章.案例研究

                                                                                        Chapter 3. Case Studies

                                                                                        没有什么比一个好例子更难忍受的了。

                                                                                        马克·吐温

                                                                                        Few things are harder to put up with than a good example.

                                                                                        Mark Twain

                                                                                          介绍

                                                                                          Introduction

                                                                                          选择这些案例研究问题(从第 43 页开始)是因为它们为许多人所熟悉,但又充满了复杂性和有趣的设计问题。这使我们能够专注于学习基本的 OOA/D、需求分析、UML 和模式,而不是解释问题。

                                                                                          These case study problems (starting on p. 43) were chosen because they're familiar to many people, yet rich with complexity and interesting design problems. That allows us to concentrate on learning fundamental OOA/D, requirements analysis, UML and patterns, rather than explaining the problems.

                                                                                            3.1. 案例研究涵盖什么,不涵盖什么?

                                                                                            3.1. What is and isn't Covered in the Case Studies?

                                                                                            通常,应用程序包括 UI 元素、核心应用程序逻辑、数据库访问以及与外部软件或硬件组件的协作。

                                                                                            Generally, applications include UI elements, core application logic, database access, and collaboration with external software or hardware components.

                                                                                            尽管 OO 技术可以应用于所有级别,但 OOA/D 的介绍侧重于核心应用程序逻辑层,并对其他层进行一些次要讨论。

                                                                                            Although OO technology can be applied at all levels, this introduction to OOA/D focuses on the core application logic layer, with some secondary discussion of the other layers.



                                                                                            探索其他层(例如 UI 层)的设计将只关注它们与 application logic 层的接口的设计。

                                                                                            Exploring design of the other layers (such as the UI layer) will just focus on the design of their interface to the application logic layer.

                                                                                            为什么在核心应用逻辑层专注于 OOA/D?

                                                                                            Why focus on OOA/D in the core application logic layer?

                                                                                            这些层的定义 p. 199

                                                                                            definition of these layers p. 199



                                                                                            • 其他层通常非常依赖于技术 / 平台。例如,要探索 Java 中 Web UI 或富客户端 UI 层的 OO 设计,我们需要详细了解 Struts 或 Swing 等框架。但对于 .NET 或 Python,选择和细节非常不同。

                                                                                            • Other layers are usually very technology/platform dependent. For example, to explore the OO design of a Web UI or rich client UI layer in Java, we would need to learn in detail about a framework such as Struts or Swing. But for .NET or Python, the choice and details are very different.

                                                                                            • 相比之下,核心逻辑层的 OO 设计在不同技术中是相似的。

                                                                                            • In contrast, the OO design of the core logic layer is similar across technologies.

                                                                                            • 在应用程序逻辑层的上下文中学到的基本 OO 设计技能适用于所有其他层或组件。

                                                                                            • The essential OO design skills learned in the context of the application logic layer are applicable to all other layers or components.

                                                                                            • 随着新框架或技术的出现,其他层的设计方法/模式往往会迅速变化。例如,在 1990 年代中期,开发人员可能会构建自己的自主开发的对象关系数据库访问层。几年后,他们更有可能使用免费的开源解决方案,例如 Hibernate(如果是 Java 技术)。

                                                                                            • The design approach/patterns for the other layers tends to change quickly as new frameworks or technologies emerge. For example, in the mid-1990s developers would probably build their own home-grown object-relational database access layer. Some years later, they were more likely to use a free, open-source solution such as Hibernate (if Java technology).

                                                                                            图 3.1.在面向对象的系统中对图层和对象进行采样,以及案例研究的重点。



                                                                                              3.2. 案例研究策略:迭代开发 + 迭代学习

                                                                                              3.2. Case Study Strategy: Iterative Development + Iterative Learning

                                                                                              本书的组织方式展示了一个迭代开发策略。OOA/D 应用于多次迭代的案例研究;第一次迭代是针对某些核心函数的。以后的迭代扩展了功能(参见图 3.2)。

                                                                                              This book is organized to show an iterative development strategy. OOA/D is applied to the case studies in multiple iterations; the first iteration is for some core functions. Later iterations expand the functionality (see Figure 3.2).

                                                                                              图 3.2.学习路径遵循迭代。



                                                                                              在迭代开发的同时,分析和设计主题的介绍、UML 表示法和模式以迭代和增量方式引入。在第一次迭代中,提出了一组核心的分析和设计主题和符号。第二次迭代扩展到新思想、UML 表示法和模式。第三次迭代也是如此。

                                                                                              In conjunction with iterative development, the presentation of analysis and design topics, UML notation, and patterns is introduced iteratively and incrementally. In the first iteration, a core set of analysis and design topics and notation is presented. The second iteration expands into new ideas, UML notation, and patterns. And likewise in the third iteration.

                                                                                                3.3. 案例一:NextGen POS 系统

                                                                                                3.3. Case One: The NextGen POS System

                                                                                                第一个案例研究是 NextGen 销售点 (POS) 系统。在这个看似简单的问题域中,我们将看到有有趣的需求和设计问题需要解决。此外,这是一个真正的问题,群体确实使用 Object 技术开发 POS 系统。

                                                                                                The first case study is the NextGen point-of-sale (POS) system. In this apparently straightforward problem domain, we shall see that there are interesting requirement and design problems to solve. In addition, it's a real problemgroups really do develop POS systems with object technologies.

                                                                                                POS 系统是一种计算机化应用程序,(部分)用于记录销售和处理付款;它通常用于零售店。它包括硬件组件,例如计算机和条形码扫描仪,以及用于运行系统的软件。它与各种服务应用程序接口,例如第三方税收计算器和库存控制。这些系统必须具有相对的容错能力;也就是说,即使远程服务暂时不可用(例如库存系统),它们仍然必须能够捕获销售并至少处理现金付款(这样企业就不会瘫痪)。

                                                                                                A POS system is a computerized application used (in part) to record sales and handle payments; it is typically used in a retail store. It includes hardware components such as a computer and bar code scanner, and software to run the system. It interfaces to various service applications, such as a third-party tax calculator and inventory control. These systems must be relatively fault-tolerant; that is, even if remote services are temporarily unavailable (such as the inventory system), they must still be capable of capturing sales and handling at least cash payments (so that the business is not crippled).

                                                                                                POS 系统越来越必须支持多种多样的客户端终端和接口。这些设备包括瘦客户端 Web 浏览器终端、具有 Java Swing 图形用户界面的常规个人计算机、触摸屏输入、无线 PDA 等。

                                                                                                A POS system increasingly must support multiple and varied client-side terminals and interfaces. These include a thin-client Web browser terminal, a regular personal computer with something like a Java Swing graphical user interface, touch screen input, wireless PDAs, and so forth.

                                                                                                此外,我们正在创建一个商业 POS 系统,我们将将其出售给在业务规则处理方面具有不同需求的不同客户。在使用该系统的情况下,每个客户都希望在某些可预测的时间点执行一组独特的逻辑,例如当开始新的销售或添加新的行项目时。因此,我们需要一种机制来提供这种灵活性和自定义。

                                                                                                Furthermore, we are creating a commercial POS system that we will sell to different clients with disparate needs in terms of business rule processing. Each client will desire a unique set of logic to execute at certain predictable points in scenarios of using the system, such as when a new sale is initiated or when a new line item is added. Therefore, we will need a mechanism to provide this flexibility and customization.

                                                                                                使用迭代开发策略,我们将进行需求、面向对象的分析、设计和实现。

                                                                                                Using an iterative development strategy, we are going to proceed through requirements, object-oriented analysis, design, and implementation.

                                                                                                  3.4. 案例二:大富翁游戏系统

                                                                                                  3.4. Case Two: The Monopoly Game System

                                                                                                  为了证明 OOA/D 的相同做法可以应用于非常不同的问题,我选择了 Monopoly® 游戏的软件版本作为另一个案例研究。尽管域和需求与 NextGen POS 等业务系统完全不同,但我们将看到域建模、使用模式的对象设计和应用 UML 仍然相关且有用。与 POS 一样,Monopoly 的软件版本是真正开发和销售的,具有丰富的客户端和 Web UI。

                                                                                                  To show that the same practices of OOA/D can apply to very different problems, I've chosen a software version of the game of Monopoly® as another case study. Although the domain and requirements are not at all like a business system such as the NextGen POS, we will see that domain modeling, object design with patterns, and applying the UML are still relevant and useful. As with a POS, software versions of Monopoly are truly developed and sold, with both rich client and Web UIs.

                                                                                                  我不会重复大富翁的规则;似乎每个国家/地区的几乎每个人在儿童或青少年时期都玩过这个游戏。如果您有任何疑问,可以在许多网站上在线获取这些规则。

                                                                                                  I won't repeat the rules for Monopoly; it seems almost every person, in every country, has played this game as a child or teenager. If you have questions, the rules are available online at many websites.

                                                                                                  游戏的软件版本将作为模拟运行。一个人将启动游戏并指示模拟玩家的数量,然后观察游戏运行到完成,显示模拟玩家回合期间的活动跟踪。

                                                                                                  The software version of the game will run as a simulation. One person will start the game and indicate the number of simulated players, and then watch while the game runs to completion, presenting a trace of the activity during the simulated player turns.

                                                                                                    第 4 章.Inception is Not the Requirements 阶段

                                                                                                    Chapter 4. Inception is Not the Requirements Phase

                                                                                                    Le mieux est l'ennemi du bien (最好的是好的敌人).

                                                                                                    伏尔泰

                                                                                                    Le mieux est l'ennemi du bien (The best is the enemy of the good).

                                                                                                    Voltaire

                                                                                                    目标

                                                                                                    Objectives

                                                                                                    • 定义起始步骤。

                                                                                                    • Define the inception step.

                                                                                                    • 请学习本节中的以下章节。

                                                                                                    • Motivate the following chapters in this section.



                                                                                                      介绍

                                                                                                      Introduction

                                                                                                      启动是为项目建立共同愿景和基本范围的最初简短步骤。它将包括对大约 10% 的用例的分析、对关键非功能性需求的分析、业务案例的创建以及开发环境的准备,以便编程可以在下一个细化阶段开始。

                                                                                                      Inception is the initial short step to establish a common vision and basic scope for the project. It will include analysis of perhaps 10% of the use cases, analysis of the critical non-functional requirement, creation of a business case, and preparation of the development environment so that programming can start in the following elaboration phase.

                                                                                                        4.1. 什么是初始计划?

                                                                                                        4.1. What is Inception?

                                                                                                        大多数项目需要一个简短的初始步骤,其中探讨了以下类型的问题:

                                                                                                        Most projects require a short initial step in which the following kinds of questions are explored:

                                                                                                        • 这个项目的愿景和商业案例是什么?

                                                                                                        • What is the vision and business case for this project?

                                                                                                        • 可行?

                                                                                                        • Feasible?

                                                                                                        • 购买和/或构建?

                                                                                                        • Buy and/or build?

                                                                                                        • 粗略不可靠的成本范围:是 10K100K 美元还是数百万美元?

                                                                                                        • Rough unreliable range of cost: Is it $10K100K or in the millions?

                                                                                                        • 我们应该继续还是停止?

                                                                                                        • Should we proceed or stop?

                                                                                                        定义愿景并获得数量级(不可靠)估计需要进行一些需求探索。但是,启动阶段的目的不是定义所有需求,或生成可信的估计或项目计划。

                                                                                                        Defining the vision and obtaining an order-of-magnitude (unreliable) estimate requires doing some requirements exploration. However, the purpose of the inception phase is not to define all the requirements, or generate a believable estimate or project plan.

                                                                                                        定义

                                                                                                        Definition

                                                                                                        这是一个关键点,当人们叠加旧的“瀑布式”思维时,在 UP 项目中一再被误解。UP 不是瀑布,第一阶段,即开始,也不是做所有要求或创建可信的估计或计划的时候。这发生在细化过程中。

                                                                                                        This is a critical point, and repeatedly misunderstood on UP projects when people superimpose old "waterfall" thinking. The UP is not the waterfall, and the first phase, inception, is not the time do all requirements or create believable estimates or plans. That happens during elaboration.



                                                                                                        冒着过于简单化的风险,我们的想法是做足够的调查,以形成对潜在新系统的总体目的和可行性的理性、合理的意见,并决定是否值得投资于更深入的探索(阐述阶段的目的)。

                                                                                                        At the risk of over-simplification, the idea is to do just enough investigation to form a rational, justifiable opinion of the overall purpose and feasibility of the potential new system, and decide if it is worthwhile to invest in deeper exploration (the purpose of the elaboration phase).

                                                                                                        大多数需求分析发生在细化阶段,与早期生产质量的编程和测试并行进行。

                                                                                                        Most requirements analysis occurs during the elaboration phase, in parallel with early production-quality programming and testing.

                                                                                                        因此,对于大多数项目来说,启动阶段应该相对较短,例如一周或几周。事实上,在许多项目中,如果它超过一周,那么就错过了开始的重点:决定项目是否值得认真调查(在阐述期间),而不是进行调查。

                                                                                                        Thus, the inception phase should be relatively short for most projects, such as one or a few weeks long. Indeed, on many projects, if it is more than a week long, then the point of inception has been missed: It is to decide if the project is worth a serious investigation (during elaboration), not to do that investigation.

                                                                                                        一句话就是《盗梦空间》:

                                                                                                        Inception in one sentence:

                                                                                                        设想产品范围、愿景和业务案例。

                                                                                                        Envision the product scope, vision, and business case.

                                                                                                        用一句话解决了主要问题:

                                                                                                        The main problem solved in one sentence:

                                                                                                        利益相关者是否对项目的愿景达成基本共识,是否值得投资进行认真的调查?

                                                                                                        Do the stakeholders have basic agreement on the vision of the project, and is it worth investing in serious investigation?



                                                                                                        这个类比有帮助吗?

                                                                                                        Does this Analogy Help?

                                                                                                        在石油业务中,当考虑新油田时,一些步骤包括:

                                                                                                        In the oil business, when a new field is being considered, some of the steps include:

                                                                                                        1.
                                                                                                        确定是否有足够的证据或商业案例来证明勘探钻探的合理性。



                                                                                                        2.
                                                                                                        如果是这样,请进行测量和勘探钻探。



                                                                                                        3.
                                                                                                        提供范围和估计信息。



                                                                                                        4.
                                                                                                        后续步骤...



                                                                                                        起始阶段就像这个类比中的第一步。在第一步中,人们不会预测有多少油,或者提取油需要多少成本或精力。虽然能够在没有勘探成本和精力的情况下回答“多少”和“何时”的问题会很好,但在石油业务中,这被认为是不现实的。

                                                                                                        The inception phase is like step one in this analogy. In step one people do not predict how much oil there is, or how much cost or effort is needed to extract it. Although it would be nice to be able to answer "how much" and "when" questions without the cost and effort of the exploration, in the oil business it is understood to not be realistic.

                                                                                                        用 UP 术语来说,现实的探索步骤是细化阶段。前面的启动阶段类似于可行性研究,以决定是否值得投资勘探钻探。只有经过认真的探索(阐述),我们才能获得数据和洞察力,以做出一些可信的估计和计划。因此,在迭代开发和 UP 中,计划和估计在初始阶段不应被视为可靠。它们只是提供了努力程度的一个数量级的感觉,以帮助决定是否继续。

                                                                                                        In UP terms, the realistic exploration step is the elaboration phase. The preceding inception phase is akin to a feasibility study to decide if it is even worth investing in exploratory drilling. Only after serious exploration (elaboration) do we have the data and insight to make somewhat believable estimates and plans. Therefore, in iterative development and the UP, plans and estimates are not to be considered reliable in the inception phase. They merely provide an order-of-magnitude sense of the level of effort, to aid the decision to continue or not.

                                                                                                          4.2. 初始计划有多长?

                                                                                                          4.2. How Long is Inception?

                                                                                                          启动的目的是为项目的目标建立一些初步的共同愿景,确定它是否可行,并决定是否值得在阐述中进行一些认真的调查。如果事先已经决定该项目一定会完成,并且显然是可行的(可能是因为团队以前做过这样的项目),那么启动阶段将特别简短。它可能包括第一次需求研讨会,规划第一次迭代,然后快速进入细化。

                                                                                                          The intent of inception is to establish some initial common vision for the objectives of the project, determine if it is feasible, and decide if it is worth some serious investigation in elaboration. If it has been decided beforehand that the project will definitely be done, and it is clearly feasible (perhaps because the team has done projects like this before), then the inception phase will be especially brief. It may include the first requirements workshop, planning for the first iteration, and then quickly moving forward to elaboration.

                                                                                                            4.3. Inception 中可以开始哪些工件?

                                                                                                            4.3. What Artifacts May Start in Inception?

                                                                                                            表 4.1 列出了常见的 inception (或 early elaboration) 工件,并指出了它们解决的问题。后续章节将更详细地研究其中的一些,尤其是 Use-Case Model。关于迭代开发的一个关键见解是要认识到,这些只是在这个阶段部分完成,将在以后的迭代中得到完善,甚至不应该创建,除非认为它们可能会增加真正的实用价值。而且由于它是开始的,调查和工件内容应该是轻量级的。

                                                                                                            Table 4.1 lists common inception (or early elaboration) artifacts and indicates the issues they address. Subsequent chapters will examine some of these in greater detail, especially the Use-Case Model. A key insight regarding iterative development is to appreciate that these are only partially completed in this phase, will be refined in later iterations, and should not even be created unless it is deemed likely they will add real practical value. And since it is inception, the investigation and artifact content should be light.

                                                                                                            表 4.1.示例 inception 工件。

                                                                                                            人工制品[]

                                                                                                            Artifact[]

                                                                                                            评论

                                                                                                            Comment

                                                                                                            愿景和商业案例

                                                                                                            Vision and Business Case

                                                                                                            描述高级目标和约束、业务案例,并提供执行摘要。

                                                                                                            Describes the high-level goals and constraints, the business case, and provides an executive summary.

                                                                                                            用例模型

                                                                                                            Use-Case Model

                                                                                                            描述功能要求。在开始时,将确定大多数用例的名称,并且可能会详细分析 10% 的用例。

                                                                                                            Describes the functional requirements. During inception, the names of most use cases will be identified, and perhaps 10% of the use cases will be analyzed in detail.

                                                                                                            补充规格

                                                                                                            Supplementary Specification

                                                                                                            描述其他要求,大多数是非功能性要求。在开始时,对将对架构产生重大影响的关键非功能性需求有一些想法是很有用的。

                                                                                                            Describes other requirements, mostly non-functional. During inception, it is useful to have some idea of the key non-functional requirements that have will have a major impact on the architecture.

                                                                                                            词汇表

                                                                                                            Glossary

                                                                                                            关键域术语和数据字典。

                                                                                                            Key domain terminology, and data dictionary.

                                                                                                            风险列表和风险管理计划

                                                                                                            Risk List & Risk Management Plan

                                                                                                            描述风险(业务、技术、资源、计划)及其缓解或响应的想法。

                                                                                                            Describes the risks (business, technical, resource, schedule) and ideas for their mitigation or response.

                                                                                                            原型和概念验证

                                                                                                            Prototypes and proof-of-concepts

                                                                                                            阐明愿景,验证技术思路。

                                                                                                            To clarify the vision, and validate technical ideas.

                                                                                                            迭代计划

                                                                                                            Iteration Plan

                                                                                                            描述在第一次细化迭代中要执行的操作。

                                                                                                            Describes what to do in the first elaboration iteration.

                                                                                                            阶段计划和软件开发计划

                                                                                                            Phase Plan & Software Development Plan

                                                                                                            细化阶段持续时间和工作量的低精度猜测。工具、人员、教育和其他资源。

                                                                                                            Low-precision guess for elaboration phase duration and effort. Tools, people, education, and other resources.

                                                                                                            开发案例

                                                                                                            Development Case

                                                                                                            此项目的自定义 UP 步骤和构件的描述。在 UP 中,人们总是为项目定制它。

                                                                                                            A description of the customized UP steps and artifacts for this project. In the UP, one always customizes it for the project.



                                                                                                            []- 这些工件在此阶段仅部分完成。它们将在后续迭代中迭代优化。名称大写意味着正式命名的 UP 工件。

                                                                                                            [] -These artifacts are only partially completed in this phase. They will be iteratively refined in subsequent iterations. Name capitalization implies an officially named UP artifact.

                                                                                                            例如,用例模型可能会列出大多数预期用例和参与者的名称,但可能只详细描述了 10% 的用例,这些用例是为了对系统范围、目的和风险进行粗略的高级设想而完成的。

                                                                                                            For example, the Use-Case Model may list the names of most of the expected use cases and actors, but perhaps only describe 10% of the use cases in detaildone in the service of developing a rough high-level vision of the system scope, purpose, and risks.

                                                                                                            请注意,一些编程工作可能会在开始时进行,以便创建“概念验证”原型,通过(通常)面向 UI 的原型阐明一些需求,以及为关键的“show stopper”技术问题进行编程实验。

                                                                                                            Note that some programming work may occur in inception in order to create "proof of concept" prototypes, to clarify a few requirements via (typically) UI-oriented prototypes, and to do programming experiments for key "show stopper" technical questions.

                                                                                                            这不是很多文档吗?

                                                                                                            Isn't That a Lot of Documentation?

                                                                                                            回想一下,工件应该被视为可选。选择只创建那些真正为项目增加价值的,如果它们的价值没有得到证明,就放弃它们。

                                                                                                            Recall that artifacts should be considered optional. Choose to create only those that really add value for the project, and drop them if their worth is not proved.

                                                                                                            由于这是渐进式开发,因此重点不是在此阶段创建完整的规范,而是初始的、粗略的文档,这些文档在细化迭代期间得到提炼,以响应早期编程和测试的宝贵反馈。

                                                                                                            And since this is evolutionary development, the point is not to create complete specifications during this phase, but initial, rough documents, that are refined during the elaboration iterations, in response to the invaluable feedback from early programming and testing.

                                                                                                            此外,创建工件或模型的重点通常不是文档或图表本身,而是思考、分析和主动准备。这就是敏捷建模的观点:建模的最大价值是提高理解,而不是记录可靠的规范。正如艾森豪威尔将军所说,“在准备战斗的过程中,我总是发现计划是无用的,但计划是必不可少的”[Nixon90BF00]。

                                                                                                            Also, often the point of creating artifacts or models is not the document or diagram itself, but the thinking, analysis, and proactive readiness. That's an Agile Modeling perspective: that the greatest value of modeling is to improve understanding, rather than to document reliable specifications. As General Eisenhower said, "In preparing for battle I have always found that plans are useless, but planning indispensable" [Nixon90, BF00].

                                                                                                            另请注意,以前项目中的工件可以在以后的项目上部分重用。跨项目在风险、项目管理、测试和环境工件方面存在许多相似之处,这是很常见的。所有 UP 项目都应以相同的方式组织工件,并使用相同的名称(Risk List、Development Case 等)。这简化了从新活动中先前项目中查找可重用的项目的过程。

                                                                                                            Note also that artifacts from previous projects can be partially reused on later ones. It is common for there to be many similarities in risk, project management, testing, and environment artifacts across projects. All UP projects should organize artifacts the same way, with the same names (Risk List, Development Case, and so on). This simplifies finding reusable artifacts from prior projects on new engagements.

                                                                                                              4.4. 你知道你不理解 Inception 的时候......

                                                                                                              4.4. You Know You Didn't Understand Inception When...

                                                                                                              • 对于大多数项目来说,它不仅仅是 “几个” 星期。

                                                                                                              • It is more than "a few" weeks long for most projects.

                                                                                                              • 尝试定义大多数要求。

                                                                                                              • There is an attempt to define most of the requirements.

                                                                                                              • 预计估计或计划是可靠的。

                                                                                                              • Estimates or plans are expected to be reliable.

                                                                                                              • 您定义架构(这应该在细化中迭代完成)。

                                                                                                              • You define the architecture (this should be done iteratively in elaboration).

                                                                                                              • 您认为正确的工作顺序应该是:1) 定义需求;2) 设计架构;3) 实施。

                                                                                                              • You believe that the proper sequence of work should be: 1) define the requirements; 2) design the architecture; 3) implement.

                                                                                                              • 没有业务案例或愿景工件。

                                                                                                              • There is no Business Case or Vision artifact.

                                                                                                              • 所有用例都编写得很详细。

                                                                                                              • All the use cases were written in detail.

                                                                                                              • 没有一个用例被详细编写;相反,应该详细编写 1020%,以便对问题的范围有一些现实的了解。

                                                                                                              • None of the use cases were written in detail; rather, 1020% should be written in detail to obtain some realistic insight into the scope of the problem.

                                                                                                                4.5. 开始时有多少 UML?

                                                                                                                4.5. How Much UML During Inception?

                                                                                                                启动的目的是收集足够的信息来建立共同的愿景,决定向前推进是否可行,以及该项目是否值得在制定阶段进行认真调查。因此,也许除了简单的 UML 用例图之外,不需要太多的图表。在开始时,我们更注重理解基本范围和 10% 的需求,主要以文本形式表示。在实践中,因此在本演示中,大多数 UML 图将发生在下一阶段阐述中。

                                                                                                                The purpose of inception is to collect just enough information to establish a common vision, decide if moving forward is feasible, and if the project is worth serious investigation in the elaboration phase. As such, perhaps beyond simple UML use case diagrams, not much diagramming is warranted. There is more focus in inception on understanding the basic scope and 10% of the requirements, expressed mostly in text forms. In practice, and thus in this presentation, most UML diagramming will occur in the next phaseelaboration.

                                                                                                                  第 5 章.进化要求

                                                                                                                  Chapter 5. Evolutionary Requirements

                                                                                                                  在我们的世界里,人们不知道自己想要什么,并愿意经历地狱来得到它。

                                                                                                                  唐·马奎斯

                                                                                                                  Ours is a world where people don't know what they want and are willing to go through hell to get it.

                                                                                                                  Don Marquis

                                                                                                                  目标

                                                                                                                  Objectives

                                                                                                                  • 激励做进化要求。

                                                                                                                  • Motivate doing evolutionary requirements.

                                                                                                                  • 定义 FURPS+ 模型。

                                                                                                                  • Define the FURPS+ model.

                                                                                                                  • 定义 UP 需求工件。

                                                                                                                  • Define the UP requirements artifacts.



                                                                                                                    介绍

                                                                                                                    Introduction

                                                                                                                    本章简要介绍了迭代和进化需求,并描述了特定的 UP 需求工件,以便为接下来面向需求的章节提供上下文。

                                                                                                                    This chapter briefly introduces iterative and evolutionary requirements, and describes specific UP requirement artifacts, to provide context for the coming requirements-oriented chapters.



                                                                                                                    此外,还探讨了一些证据,这些证据说明了面向瀑布的需求分析方法的徒劳和不熟练,其中试图在开始开发之前定义所谓的 “完整” 规范。

                                                                                                                    In also explores some evidence illustrating the futility and unskillfulness of waterfall-oriented requirements analysis approaches, in which there is an attempt to define so-called "complete" specifications before starting development.

                                                                                                                      5.1. 定义:要求

                                                                                                                      5.1. Definition: Requirements

                                                                                                                      需求是系统(更广泛地说,项目必须符合)的能力和条件 [JBR99]。

                                                                                                                      Requirements are capabilities and conditions to which the systemand more broadly, the projectmust conform [JBR99].

                                                                                                                      UP 推广了一组最佳实践,其中之一就是管理需求。这并不意味着在项目第一阶段编程之前试图完全定义和稳定需求的瀑布式态度,而是在不可避免地变化和不明确的利益相关者愿望的背景下,这意味着“一种系统的方法来查找、记录、组织和跟踪系统不断变化的需求”[RUP]。

                                                                                                                      The UP promotes a set of best practices, one of which is manage requirements. This does not mean the waterfall attitude of attempting to fully define and stabilize the requirements in the first phase of a project before programming, but ratherin the context of inevitably changing and unclear stakeholder's wishes, this means"a systematic approach to finding, documenting, organizing, and tracking the changing requirements of a system" [RUP].

                                                                                                                      简而言之,迭代和熟练地做这件事,而不是马虎。

                                                                                                                      In short, doing it iteratively and skillfully, and not being sloppy.

                                                                                                                      需求分析的一个主要挑战是以一种与客户和开发团队成员清楚地对话的形式找到、沟通和记住(通常意味着写下)真正需要的东西。

                                                                                                                      A prime challenge of requirements analysis is to find, communicate, and remember (that usually means write down) what is really needed, in a form that clearly speaks to the client and development team members.

                                                                                                                        5.2. 进化 vs. 瀑布要求

                                                                                                                        5.2. Evolutionary vs. Waterfall Requirements

                                                                                                                        请注意,管理需求 (management requirements) 的定义中,这个词发生了变化。UP 将需求的变化作为项目的基本驱动力。这非常重要,也是瀑布式思维与迭代和进化思维的核心。

                                                                                                                        Notice the word changing in the definition of what it means to manage requirements. The UP embraces change in requirements as a fundamental driver on projects. That's incredibly important and at the heart of waterfall versus iterative and evolutionary thinking.

                                                                                                                        在 UP 和其他进化方法(Scrum、XP、FDD 等)中,我们早在大多数需求被分析或指定之前就开始了生产质量的编程和测试,也许当只有 10% 或 20% 的架构上最重要、风险最高和高业务价值的需求被指定时。

                                                                                                                        In the UP and other evolutionary methods (Scrum, XP, FDD, and so on), we start production-quality programming and testing long before most of the requirements have been analyzed or specifiedperhaps when only 10% or 20% of the most architecturally significant, risky, and high-business-value requirements have been specified.

                                                                                                                        流程细节是什么?如何在迭代中结合早期设计和编程进行部分的、进化的需求分析?请参阅第 25 页的“如何进行迭代和进化分析和设计?它提供了简短的描述和图片来帮助解释该过程。请参阅第 95 页上的“Process: How to Work with Use Cases in Iterative Methods?”。它有更详细的讨论。

                                                                                                                        What are the process details? How to do partial, evolutionary requirements analysis combined with early design and programming, in iterations? See "How to do Iterative and Evolutionary Analysis and Design?" on page 25. It provides a brief description and a picture to help explain the process. See "Process: How to Work With Use Cases in Iterative Methods?" on page 95. It has more detailed discussion.

                                                                                                                        谨慎!

                                                                                                                        Caution!

                                                                                                                        如果您发现自己在一个所谓的 UP 或迭代项目中,它试图在开始编程和测试之前指定大部分或全部需求(用例等),那么就会存在一个深刻的误解:它不是一个健康的 UP 或迭代项目。

                                                                                                                        If you find yourself on a so-called UP or iterative project that attempts to specify most or all of the requirements (use cases, and so forth) before starting to program and test, there is a profound misunderstandingit is not a healthy UP or iterative project.



                                                                                                                        在 1960 年代和 1970 年代(当我开始作为开发人员工作时),人们仍然普遍认为对软件项目(即瀑布)进行完整的、早期的需求分析的有效性。从 1980 年代开始,有证据表明这是不熟练的,并导致了许多失败;旧观念植根于错误的范式,即将软件项目视为类似于可预测的大规模制造,具有较低的更改率。但软件属于新产品开发领域,具有很高的变化范围和高度的新颖性和发现性。

                                                                                                                        In the 1960s and 1970s (when I started work as a developer) there was still a common speculative belief in the efficacy of full, early requirements analysis for software projects (i.e., the waterfall). Starting in the 1980s, there arose evidence this was unskillful and led to many failures; the old belief was rooted in the wrong paradigm of viewing a software project as similar to predictable mass manufacturing, with low change rates. But software is in the domain of new product development, with high change ranges and high degrees of novelty and discovery.

                                                                                                                        回想一下关键统计数据,平均而言,软件项目中 25% 的需求发生变化。因此,任何试图在一开始就冻结或完全定义需求的方法都是有根本缺陷的,它基于一个错误的假设,并且与不可避免的变化作斗争或否认。

                                                                                                                        Recall the key statistic that, on average, 25% of the requirements change on software projects. Any method that therefore attempts to freeze or fully define requirements at the start is fundamentally flawed, based on a false assumption, and fighting or denying the inevitable change.

                                                                                                                        《变革研究》 第24

                                                                                                                        change research p. 24



                                                                                                                        例如,对 1,027 个软件项目的失败因素的研究 [Thomas01] 强调了这一点。发现是什么?尝试瀑布式实践(包括详细的前期需求)是导致失败的最大因素,在 82% 的项目中被列为头号问题。引用结论:

                                                                                                                        Underlining this point, for example, was a study of failure factors on 1,027 software projects [Thomas01]. The findings? Attempting waterfall practices (including detailed up-front requirements) was the single largest contributing factor for failure, being cited in 82% of the projects as the number one problem. To quote the conclusion:

                                                                                                                        …在交付这些需求之前,先定义完整的需求,然后再进行长时间的间隔,这种方法不再适用。

                                                                                                                        不断变化的业务需求的高排名表明,任何假设一旦记录了需求就不会有重大变化的假设都是有根本缺陷的,并且花费大量时间和精力将它们定义到最高级别是不合适的。

                                                                                                                        … the approach of full requirements definition followed by a long gap before those requirements are delivered is no longer appropriate.

                                                                                                                        The high ranking of changing business requirements suggests that any assumption that there will be little significant change to requirements once they have been documented is fundamentally flawed, and that spending significant time and effort defining them to the maximum level is inappropriate.

                                                                                                                        另一个相关的研究结果回答了这个问题:当尝试瀑布式需求分析时,有多少过早指定的功能在最终软件产品中实际上是有用的?在一项对数千个项目的研究 [Johnson02] 中,结果非常揭示 45% 的此类功能从未使用过,另外 19% 的功能“很少”使用。参见图 5.1。几乎 65% 的瀑布流指定功能几乎没有价值!

                                                                                                                        Another relevant research result answers this question: When waterfall requirements analysis is attempted, how many of the prematurely early specified features are actually useful in the final software product? In a study [Johnson02] of thousands of projects, the results are quite revealing45% of such features were never used, and an additional 19% were "rarely" used. See Figure 5.1. Almost 65% of the waterfall-specified features were of little or no value!

                                                                                                                        图 5.1.瀑布指定功能的实际使用情况。



                                                                                                                        这些结果并不意味着解决方案是在项目的第一天就开始敲打代码,而忘记需求分析或记录需求。有一条中间道路:迭代和进化需求分析与早期有时间限制的迭代开发以及频繁的利益相关者参与、评估和对部分结果的反馈相结合。

                                                                                                                        These results don't imply that the solution is to start pounding away at the code near Day One of the project, and forget about requirements analysis or recording requirements. There is a middle way: iterative and evolutionary requirements analysis combined with early timeboxed iterative development and frequent stakeholder participation, evaluation, and feedback on partial results.

                                                                                                                          5.3. 寻找需求的巧妙方法有哪些?

                                                                                                                          5.3. What are Skillful Means to Find Requirements?

                                                                                                                          要查看 UP 最佳实践管理要求,请执行以下操作:

                                                                                                                          To review the UP best practice manage requirements:

                                                                                                                          …一种用于查找、记录、组织和跟踪系统不断变化的需求的系统方法。[鲁普]

                                                                                                                          …a systematic approach to finding, documenting, organizing, and tracking the changing requirements of a system. [RUP]

                                                                                                                          除了改变之外,词也很重要;也就是说,UP 鼓励通过各种技术进行巧妙的启发,例如与客户一起编写用例、包括开发人员和客户的需求研讨会、与代理客户的焦点小组以及向客户演示每次迭代的结果,以征求反馈。

                                                                                                                          Besides changing, the word finding is important; that is, the UP encourages skillful elicitation via techniques such as writing use cases with customers, requirements workshops that include both developers and customers, focus groups with proxy customers, and a demo of the results of each iteration to the customers, to solicit feedback.

                                                                                                                          UP 欢迎任何可以增加价值并增加用户参与度的需求获取方法。即使是简单的 XP“故事卡”实践在 UP 项目中也是可以接受的,如果它可以有效地工作(它需要项目室中有一名全职客户专家在场,这是一种出色的实践,但通常很难实现)。

                                                                                                                          The UP welcomes any requirements elicitation method that can add value and that increases user participation. Even the simple XP "story card" practice is acceptable on a UP project, if it can be made to work effectively (it requires the presence of a full-time customer-expert in the project rooman excellent practice but often difficult to achieve).

                                                                                                                            5.4. 需求的类型和类别有哪些?

                                                                                                                            5.4. What are the Types and Categories of Requirements?

                                                                                                                            在 UP 中,需求根据 FURPS+ 模型 [Grady92] 进行分类,这是一个有用的助记词,含义如下:[1]

                                                                                                                            In the UP, requirements are categorized according to the FURPS+ model [Grady92], a useful mnemonic with the following meaning:[1]

                                                                                                                            [1] 书籍和标准组织发布了几个需求分类和质量属性系统,例如 ISO 9126(类似于 FURPS+ 列表),以及来自软件工程研究所 (SEI) 的几个系统;any 可用于 UP 项目。

                                                                                                                            [1] There are several systems of requirements categorization and quality attributes published in books and by standards organizations, such as ISO 9126 (which is similar to the FURPS+ list), and several from the Software Engineering Institute (SEI); any can be used on a UP project.

                                                                                                                            • 功能特性、功能、安全性。

                                                                                                                            • Functional features, capabilities, security.

                                                                                                                            • 可用性 人为因素、帮助、文档。

                                                                                                                            • Usability human factors, help, documentation.

                                                                                                                            • 可靠性、故障频率、可恢复性、可预测性。

                                                                                                                            • Reliability frequency of failure, recoverability, predictability.

                                                                                                                            • 性能响应时间、吞吐量、准确性、可用性、资源使用情况。

                                                                                                                            • Performance response times, throughput, accuracy, availability, resource usage.

                                                                                                                            • 可支持性 适应性 、 可维护性 、 国际化 、 可配置性 。

                                                                                                                            • Supportability adaptability, maintainability, internationalization, configurability.

                                                                                                                            FURPS+ 中的“+”表示辅助因素和子因素,例如:

                                                                                                                            The "+" in FURPS+ indicates ancillary and sub-factors, such as:

                                                                                                                            • 实现资源限制、语言和工具、硬件......

                                                                                                                            • Implementation resource limitations, languages and tools, hardware, ...

                                                                                                                            • 通过与外部系统接口施加的接口约束。

                                                                                                                            • Interface constraints imposed by interfacing with external systems.

                                                                                                                            • 操作设置中的操作系统管理。

                                                                                                                            • Operations system management in its operational setting.

                                                                                                                            • 包装例如,一个物理盒子。

                                                                                                                            • Packaging for example, a physical box.

                                                                                                                            • 合法许可等。

                                                                                                                            • Legal licensing and so forth.

                                                                                                                            使用 FURPS+ 类别(或某些分类方案)作为需求覆盖率的清单是有帮助的,以减少不考虑系统的某些重要方面的风险。

                                                                                                                            It is helpful to use FURPS+ categories (or some categorization scheme) as a checklist for requirements coverage, to reduce the risk of not considering some important facet of the system.

                                                                                                                            其中一些要求统称为系统的质量属性、质量要求或“-ilities”。这些因素包括可用性、可靠性、性能和可支持性。在通常的用法中,需求分为功能性(行为)和非功能性(其他一切);有些人不喜欢这种宽泛的概括 [BCK98],但它的使用非常广泛。

                                                                                                                            Some of these requirements are collectively called the quality attributes, quality requirements, or the "-ilities" of a system. These include usability, reliability, performance, and supportability. In common usage, requirements are categorized as functional (behavioral) or non-functional (everything else); some dislike this broad generalization [BCK98], but it is very widely used.

                                                                                                                            正如我们在探索架构分析时将看到的那样,质量属性对系统的架构有很大的影响。例如,高性能、高可靠性的要求将影响软件和硬件组件的选择及其配置。

                                                                                                                            As we shall see when exploring architectural analysis, the quality attributes have a strong influence on the architecture of a system. For example, a high-performance, high-reliability requirement will influence the choice of software and hardware components, and their configuration.



                                                                                                                              5.5. UP Artifacts 中的需求是如何组织的?

                                                                                                                              5.5. How are Requirements Organized in UP Artifacts?

                                                                                                                              UP 提供了多个需求工件。与所有 UP 工件一样,它们是可选的。主要包括:

                                                                                                                              The UP offers several requirements artifacts. As with all UP artifacts, they are optional. Key ones include:

                                                                                                                              • 用例模型使用系统的一组典型场景。主要针对功能 (行为) 要求。

                                                                                                                              • Use-Case Model A set of typical scenarios of using a system. There are primarily for functional (behavioral) requirements.

                                                                                                                              • 补充规格基本上,一切都不在用例中。此工件主要用于所有非功能性要求,例如性能或许可。它也是记录未作为用例表达(或可表达)的功能特性的地方;例如,报表生成。

                                                                                                                              • Supplementary Specification Basically, everything not in the use cases. This artifact is primarily for all non-functional requirements, such as performance or licensing. It is also the place to record functional features not expressed (or expressible) as use cases; for example, a report generation.

                                                                                                                              • 词汇表在最简单的形式中,词汇表定义了值得注意的术语。它还包含数据字典的概念,该字典记录与数据相关的要求,例如验证规则、可接受的值等。Glossary 可以详细说明任何元素:对象的属性、操作调用的参数、报表布局等。

                                                                                                                              • Glossary In its simplest form, the Glossary defines noteworthy terms. It also encompasses the concept of the data dictionary, which records requirements related to data, such as validation rules, acceptable values, and so forth. The Glossary can detail any element: an attribute of an object, a parameter of an operation call, a report layout, and so forth.

                                                                                                                              • 视觉总结了 Use-Case Model 和 Supplementary Specification 中详细说明的高级要求,并总结了项目的业务案例。一个简短的执行概述文档,用于快速了解项目的宏大构想。

                                                                                                                              • Vision Summarizes high-level requirements that are elaborated in the Use-Case Model and Supplementary Specification, and summarizes the business case for the project. A short executive overview document for quickly learning the project's big ideas.

                                                                                                                              • 业务规则业务规则(也称为域规则)通常描述超越一个软件项目的要求或策略,它们在域或业务中是必需的,并且许多应用程序可能需要遵守它们。一个很好的例子是政府税法。域规则详细信息可以记录在补充规范中,但是因为它们通常比一个软件项目更持久和适用,所以将它们放在一个中央业务规则工件中(由公司的所有分析师共享)可以更好地重用分析工作。

                                                                                                                              • Business Rules Business rules (also called Domain Rules) typically describe requirements or policies that transcend one software projectthey are required in the domain or business, and many applications may need to conform to them. An excellent example is government tax laws. Domain rule details may be recorded in the Supplementary Specification, but because they are usually more enduring and applicable than for one software project, placing them in a central Business Rules artifact (shared by all analysts of the company) makes for better reuse of the analysis effort.

                                                                                                                              这些工件的正确格式是什么?

                                                                                                                              What is the Correct Format for these Artifacts?

                                                                                                                              在 UP 中,所有工件都是信息抽象;它们可以存储在 Web 页面(例如在 Wiki Web 中)、墙贴海报或任何可以想象的变体上。在线 RUP 文档产品包含构件的模板,但这些是可选的辅助工具,可以忽略。

                                                                                                                              In the UP, all artifacts are information abstractions; they could be stored on Web pages (such as in a Wiki Web), wall posters, or any variation imaginable. The online RUP documentation product contains templates for the artifacts, but these are an optional aid, and can be ignored.

                                                                                                                                5.6. 这本书包含这些工件的示例吗?

                                                                                                                                5.6. Does the Book Contain Examples of These Artifacts?

                                                                                                                                是的!这本书主要是在迭代过程中对 OOA/D 的介绍,而不是需求分析,但是在没有一些需求示例或上下文的情况下探索 OOA/D 会给出不完整的画面,它忽略了需求对 OOA/D 的影响。拥有一个更大的关键 UP 需求工件示例非常有用。在哪里可以找到示例:

                                                                                                                                Yes! This book is primarily an introduction to OOA/D in an iterative process rather than requirements analysis, but exploring OOA/D without some example or context of the requirements gives an incomplete pictureit ignores the influence of requirements on OOA/D. And it's simply useful to have a larger example of key UP requirements artifacts. Where to find the examples:

                                                                                                                                需求工件

                                                                                                                                Requirement Artifact

                                                                                                                                哪里?

                                                                                                                                Where?

                                                                                                                                评论

                                                                                                                                Comment

                                                                                                                                用例模型

                                                                                                                                Use-Case Model

                                                                                                                                引言61

                                                                                                                                Introduction p. 61

                                                                                                                                中级 第 493

                                                                                                                                Intermediate p. 493

                                                                                                                                用例在 UP 中很常见,并且是 OOA/D 的输入,因此在前面的章节中进行了详细描述。

                                                                                                                                Use cases are common in the UP and an input to OOA/D, and thus described in detail in an early chapter.

                                                                                                                                补充规范、词汇表、愿景、业务规则

                                                                                                                                Supplementary Specification, Glossary, Vision, Business Rules

                                                                                                                                案例研究示例,第 101

                                                                                                                                Case study examples p. 101

                                                                                                                                这些是为了保持一致性而提供的,但可以跳过,而不是 OOA/D 主题。

                                                                                                                                These are provided for consistency, but can be skippednot an OOA/D topic.



                                                                                                                                  5.7. 推荐资源

                                                                                                                                  5.7. Recommended Resources

                                                                                                                                  与用例的需求相关的参考资料将在后续章节中介绍。面向用例的需求文本,例如 Writing Effective Use Cases [Cockburn01] 是需求研究的推荐起点,而不是更通用(通常是传统的)需求文本。

                                                                                                                                  References related to requirements with use cases are covered in a subsequent chapter. Use-case-oriented requirements texts, such as Writing Effective Use Cases [Cockburn01] are the recommended starting point in requirements study, rather than more general (and usually, traditional) requirements texts.

                                                                                                                                  在软件工程知识体系 (SWEBOK) 的保护伞下,人们在讨论需求和各种软件工程主题方面做出了广泛的努力,可在 www.swebok.org 上获得。

                                                                                                                                  There is a broad effort to discuss requirementsand a wide variety of software engineering topicsunder the umbrella of the Software Engineering Body of Knowledge (SWEBOK), available at www.swebok.org.

                                                                                                                                  SEI (www.sei.cmu.edu) 有几项与质量要求相关的提案。ISO 9126、IEEE Std 830 和 IEEE Std 1061 是与要求和质量属性相关的标准,可在 Web 上的各种站点上找到。

                                                                                                                                  The SEI (www.sei.cmu.edu) has several proposals related to quality requirements. The ISO 9126, IEEE Std 830, and IEEE Std 1061 are standards related to requirements and quality attributes, and available on the Web at various sites.

                                                                                                                                  关于一般需求书籍的警告,即使是那些声称涵盖用例、迭代开发甚至 UP 中的需求的书籍:

                                                                                                                                  A caution regarding general requirements books, even those that claim to cover use cases, iterative development, or indeed even requirements in the UP:

                                                                                                                                  大多数都是在进行设计和实现之前,以重要或“彻底”的前期需求定义的瀑布式偏见编写的。那些也提到迭代开发的书可能只是肤浅地这样做,也许最近添加了“迭代”材料以迎合现代趋势。他们可能有很好的需求启发和组织技巧,但并不代表迭代和进化分析的准确观点。

                                                                                                                                  Most are written with a waterfall bias of significant or "thorough" up-front requirements definition before moving on to design and implementation. Those books that also mention iterative development may do so superficially, perhaps with "iterative" material recently added to appeal to modern trends. They may have good requirements elicitation and organization tips, but don't represent an accurate view of iterative and evolutionary analysis.

                                                                                                                                  任何建议 “尝试定义大部分需求,然后继续进行设计和实现” 的建议变体都与迭代进化开发和 UP 不一致。

                                                                                                                                  Any variant of advice that suggests "try to define most of the requirements, and then move forward to design and implementation" is inconsistent with iterative evolutionary development and the UP.

                                                                                                                                    第 6 章.使用案例

                                                                                                                                    Chapter 6. Use Cases

                                                                                                                                    从生活中获得你想要的东西不可或缺的第一步:决定你想要什么。

                                                                                                                                    本·斯坦

                                                                                                                                    The indispensable first step to getting the things you want out of life: decide what you want.

                                                                                                                                    Ben Stein

                                                                                                                                    目标

                                                                                                                                    Objectives

                                                                                                                                    • 确定并编写使用案例。

                                                                                                                                    • Identify and write use cases.

                                                                                                                                    • 使用简短、休闲和正装的形式,以基本风格。

                                                                                                                                    • Use the brief, casual, and fully dressed formats, in an essential style.

                                                                                                                                    • 应用测试以确定合适的用例。

                                                                                                                                    • Apply tests to identify suitable use cases.

                                                                                                                                    • 将用例分析与迭代开发相关联。

                                                                                                                                    • Relate use case analysis to iterative development.



                                                                                                                                      介绍

                                                                                                                                      Introduction

                                                                                                                                      用例是文本故事,广泛用于发现和记录需求。它们会影响项目的许多方面,包括 OOA/Dand,并且将被输入到案例研究中的许多后续工件中。本章探讨了基本概念,包括如何编写用例和绘制 UML 用例图。本章还展示了分析技能相对于了解 UML 表示法的价值;UML 用例图很容易学习,但识别和编写良好用例的许多指南需要数周或更长时间才能完全消化。

                                                                                                                                      Use cases are text stories, widely used to discover and record requirements. They influence many aspects of a projectincluding OOA/Dand will be input to many subsequent artifacts in the case studies. This chapter explores basic concepts, including how to write use cases and draw a UML use case diagram. This chapter also shows the value of analysis skill over knowing UML notation; the UML use case diagram is trivial to learn, but the many guidelines to identify and write good use cases take weeksor longerto fully digest.



                                                                                                                                      UP 工件的影响,重点是文本用例,如图 6.1 所示。高级目标和用例图是创建用例文本的输入。这些用例反过来会影响许多其他分析、设计、实施、项目管理和测试工件。

                                                                                                                                      The influence of UP artifacts, with an emphasis on text use cases, is shown in Figure 6.1. High-level goals and use case diagrams are input to the creation of the use case text. The use cases can in turn influence many other analysis, design, implementation, project management, and test artifacts.

                                                                                                                                      图 6.1.示例 UP 伪影影响。



                                                                                                                                        6.1. 示例

                                                                                                                                        6.1. Example

                                                                                                                                        非正式地,用例是一些参与者使用系统实现目标的文本故事。下面是一个示例简要格式用例:

                                                                                                                                        Informally, use cases are text stories of some actor using a system to meet goals. Here is an example brief format use case:

                                                                                                                                        流程销售:客户带着要购买的商品到达结账处。收银员使用 POS 系统记录每个购买的商品。系统显示汇总和行项目详细信息。客户输入付款信息,系统验证并记录这些信息。系统更新清单。客户从系统收到收据,然后带着物品离开。

                                                                                                                                        Process Sale: A customer arrives at a checkout with items to purchase. The cashier uses the POS system to record each purchased item. The system presents a running total and line-item details. The customer enters payment information, which the system validates and records. The system updates inventory. The customer receives a receipt from the system and then leaves with the items.

                                                                                                                                        请注意,用例不是图表,而是文本。关注次要值的 UML 用例图而不是重要的用例文本是用例新手的常见错误。

                                                                                                                                        Notice that use cases are not diagrams, they are text. Focusing on secondary-value UML use case diagrams rather than the important use case text is a common mistake for use case novices.



                                                                                                                                        用例通常需要比此示例更详细或更结构化,但本质是通过编写使用系统实现用户目标的故事来发现和记录功能需求;即 case of use[1] 这不应该是一个难的想法,尽管发现需要什么并写好它通常很困难。

                                                                                                                                        Use cases often need to be more detailed or structured than this example, but the essence is discovering and recording functional requirements by writing stories of using a system to fulfill user goals; that is, cases of use.[1] It isn't supposed to be a difficult idea, although it's often difficult to discover what's needed and write it well.

                                                                                                                                        [1] 瑞典语的原始术语字面意思是“用例”。

                                                                                                                                        [1] The original term in Swedish literally translates as "usage case."

                                                                                                                                          6.2. 定义:什么是参与者、场景和用例?

                                                                                                                                          6.2. Definition: What are Actors, Scenarios, and Use Cases?

                                                                                                                                          首先,一些非正式的定义:参与者是具有行为的事物,例如一个人(由角色标识)、计算机系统或组织;例如,收银员。

                                                                                                                                          First, some informal definitions: an actor is something with behavior, such as a person (identified by role), computer system, or organization; for example, a cashier.

                                                                                                                                          场景是参与者和系统之间的特定操作和交互序列;它也称为用例实例。这是一个使用系统的特殊故事,或者说是用例的一条路径;例如,使用现金成功购买物料的方案,或由于信用付款被拒绝而无法购买物料的方案。

                                                                                                                                          A scenario is a specific sequence of actions and interactions between actors and the system; it is also called a use case instance. It is one particular story of using a system, or one path through the use case; for example, the scenario of successfully purchasing items with cash, or the scenario of failing to purchase items because of a credit payment denial.

                                                                                                                                          因此,非正式地,用例是相关成功和失败场景的集合,用于描述参与者使用系统来支持目标。例如,下面是一个具有替代场景的休闲格式使用案例:

                                                                                                                                          Informally then, a use case is a collection of related success and failure scenarios that describe an actor using a system to support a goal. For example, here is a casual format use case with alternate scenarios:

                                                                                                                                          处理退货

                                                                                                                                          主要成功场景: 客户到达结账处,携带要退货的商品。收银员使用 POS 系统记录每件退回的物品......

                                                                                                                                          备选方案

                                                                                                                                          如果买家通过信用卡付款,并且其信用卡账户的赔偿交易被拒绝,请通知买家并使用现金付款。

                                                                                                                                          如果在系统中找不到商品标识符,请通知收银员并建议手动输入标识符代码(可能已损坏)。

                                                                                                                                          如果系统检测到无法与外部会计系统通信,则...

                                                                                                                                          Handle Returns

                                                                                                                                          Main Success Scenario: A customer arrives at a checkout with items to return. The cashier uses the POS system to record each returned item …

                                                                                                                                          Alternate Scenarios:

                                                                                                                                          If the customer paid by credit, and the reimbursement transaction to their credit account is rejected, inform the customer and pay them with cash.

                                                                                                                                          If the item identifier is not found in the system, notify the Cashier and suggest manual entry of the identifier code (perhaps it is corrupted).

                                                                                                                                          If the system detects failure to communicate with the external accounting system, …

                                                                                                                                          现在,场景(用例实例)已经定义,RUP 提供的替代但类似的用例定义将更有意义:

                                                                                                                                          Now that scenarios (use case instances) are defined, an alternate, but similar definition of a use case provided by the RUP will make better sense:

                                                                                                                                          一组用例实例,其中每个实例都是系统执行的一系列操作,这些操作会为特定参与者 [RUP] 生成有价值的可观察结果。

                                                                                                                                          A set of use-case instances, where each instance is a sequence of actions a system performs that yields an observable result of value to a particular actor [RUP].

                                                                                                                                            6.3. 用例和用例模型

                                                                                                                                            6.3. Use Cases and the Use-Case Model

                                                                                                                                            UP 在需求学科中定义了用例模型。首先,这是所有书面用例的集合;它是系统功能和环境的模型。

                                                                                                                                            The UP defines the Use-Case Model within the Requirements discipline. Primarily, this is the set of all written use cases; it is a model of the system's functionality and environment.

                                                                                                                                            用例是文本文档,而不是图表,用例建模主要是编写文本的行为,而不是绘制图表。

                                                                                                                                            Use cases are text documents, not diagrams, and use-case modeling is primarily an act of writing text, not drawing diagrams.



                                                                                                                                            用例模型并不是 UP 中唯一的需求工件。此外,还有 Supplementary Specification、Glossary、Vision 和 Business Rules。这些对于需求分析都很有用,但在这一点上是次要的。

                                                                                                                                            The Use-Case Model is not the only requirement artifact in the UP. There are also the Supplementary Specification, Glossary, Vision, and Business Rules. These are all useful for requirements analysis, but secondary at this point.



                                                                                                                                            用例模型可以选择包括 UML 用例图,以显示用例和参与者的名称以及它们之间的关系。这提供了系统及其环境的一个很好的上下文图。它还提供了一种按名称列出使用案例的快速方法。

                                                                                                                                            The Use-Case Model may optionally include a UML use case diagram to show the names of use cases and actors, and their relationships. This gives a nice context diagram of a system and its environment. It also provides a quick way to list the use cases by name.



                                                                                                                                            用例没有面向对象的内容;我们在编写它们时不进行 OO 分析。这不是问题,用例广泛适用,这增加了它们的实用性。也就是说,使用案例是经典 OOA/D 的关键要求输入。

                                                                                                                                            There is nothing object-oriented about use cases; we're not doing OO analysis when writing them. That's not a problemuse cases are broadly applicable, which increases their usefulness. That said, use cases are a key requirements input to classic OOA/D.

                                                                                                                                              6.4. 动机:为什么是用例?

                                                                                                                                              6.4. Motivation: Why Use Cases?

                                                                                                                                              我们有目标,并希望计算机帮助实现这些目标,从记录销售到玩游戏,再到估计未来油井的石油流量。聪明的分析师发明了许多捕捉目标的方法,但最好的方法都是简单而熟悉的。为什么?这使得客户更容易为他们的定义和审查做出贡献。这降低了错过标记的风险。这似乎是一个随意的评论,但它很重要。研究人员编造了他们理解的复杂分析方法,但这些方法会让你的普通商务人士陷入昏迷!缺乏用户对软件项目的参与几乎是项目失败的首要原因 [Larman03],因此任何可以帮助他们保持参与的东西都是真正可取的。

                                                                                                                                              We have goals and want computers to help meet them, ranging from recording sales to playing games to estimating the flow of oil from future wells. Clever analysts have invented many ways to capture goals, but the best are simple and familiar. Why? This makes it easierespecially for customersto contribute to their definition and review. That lowers the risk of missing the mark. This may seem like an off-hand comment, but it's important. Researchers have concocted complex analysis methods that they understand, but that send your average business person into a coma! Lack of user involvement in software projects is near the top of the list of reasons for project failure [Larman03], so anything that can help keep them involved is truly desirable.

                                                                                                                                              用例是帮助保持简单的好方法,并使领域专家或需求捐赠者能够自己编写(或参与编写)用例。

                                                                                                                                              Use cases are a good way to help keep it simple, and make it possible for domain experts or requirement donors to themselves write (or participate in writing) use cases.



                                                                                                                                              用例的另一个价值是它们强调用户目标和观点;我们提出这个问题:“谁在使用该系统,他们的典型使用场景是什么,他们的目标是什么?与简单地要求提供系统功能列表相比,这是一种更加以用户为中心的重点。

                                                                                                                                              Another value of use cases is that they emphasize the user goals and perspective; we ask the question "Who is using the system, what are their typical scenarios of use, and what are their goals?" This is a more user-centric emphasis compared to simply asking for a list of system features.

                                                                                                                                              关于用例的文章已经写了很多,尽管有价值,但有创造力的人往往会用层次复杂或过于复杂的层次来掩盖一个简单的想法。通常,可以通过过度关注次要问题(如用例图、用例关系、用例包等)来发现新手用例建模者(或严肃的 A 型分析师),而不是专注于简单地编写文本故事的艰苦工作。

                                                                                                                                              Much has been written about use cases, and though worthwhile, creative people often obscure a simple idea with layers of sophistication or over-complication. It is usually possible to spot a novice use-case modeler (or a serious Type-A analyst!) by an over-concern with secondary issues such as use case diagrams, use case relationships, use case packages, and so forth, rather than a focus on the hard work of simply writing the text stories.

                                                                                                                                              也就是说,用例的一个优势是能够在复杂性和正式性方面进行扩展和缩减。

                                                                                                                                              That said, a strength of use cases is the ability to scale both up and down in terms of sophistication and formality.

                                                                                                                                                6.5. 定义:用例是功能需求吗?

                                                                                                                                                6.5. Definition: Are Use Cases Functional Requirements?

                                                                                                                                                用例需求,主要是指示系统将做什么的功能或行为要求。就 FURPS+ 需求类型而言,它们强调 “F” (功能或行为),但也可用于其他类型,尤其是当这些其他类型与用例密切相关时。在 UP和许多现代方法中,用例是推荐用于发现和定义其的核心机制。

                                                                                                                                                Use cases are requirements, primarily functional or behavioral requirements that indicate what the system will do. In terms of the FURPS+ requirements types, they emphasize the "F" (functional or behavioral), but can also be used for other types, especially when those other types strongly relate to a use case. In the UPand many modern methodsuse cases are the central mechanism that is recommended for their discovery and definition.

                                                                                                                                                FURPS+ 第 56

                                                                                                                                                FURPS+ p. 56



                                                                                                                                                一个相关的观点是,用例定义了系统行为方式的契约 [Cockburn01]。

                                                                                                                                                A related viewpoint is that a use case defines a contract of how a system will behave [Cockburn01].

                                                                                                                                                需要明确的是:用例确实是需求(尽管不是所有需求)。有些人只认为需求是 “系统应该做...”函数或功能列表。事实并非如此,用例的一个关键思想是(通常)降低详细的旧式功能列表的重要性或使用,而是为功能需求编写用例。稍后的章节将详细介绍这一点。

                                                                                                                                                To be clear: Use cases are indeed requirements (although not all requirements). Some think of requirements only as "the system shall do…" function or feature lists. Not so, and a key idea of use cases is to (usually) reduce the importance or use of detailed old-style feature lists and rather write use cases for the functional requirements. More on this point in a later section.

                                                                                                                                                  6.6. 定义:什么是三种 Actors?

                                                                                                                                                  6.6. Definition: What are Three Kinds of Actors?

                                                                                                                                                  参与者是任何具有行为的东西,包括当它调用其他系统的服务时被讨论的系统 (SuD) 本身。[2] 主要参与者和配角将出现在用例文本的 action steps 中。参与者不仅是人扮演的角色,也是组织、软件和机器扮演的角色。与 SuD 相关的外部参与者分为三种:

                                                                                                                                                  An actor is anything with behavior, including the system under discussion (SuD) itself when it calls upon the services of other systems.[2] Primary and supporting actors will appear in the action steps of the use case text. Actors are roles played not only by people, but by organizations, software, and machines. There are three kinds of external actors in relation to the SuD:

                                                                                                                                                  [2] 这是对参与者替代定义的改进和改进,包括 UML 和 UP 早期版本中的定义 [Cockburn97]。较旧的定义不一致地将 SuD 排除在参与者之外,即使它调用其他系统的服务也是如此。所有实体都可以扮演多个角色,包括 SuD。

                                                                                                                                                  [2] This was a refinement and improvement to alternate definitions of actors, including those in early versions of the UML and UP [Cockburn97]. Older definitions inconsistently excluded the SuD as an actor, even when it called upon services of other systems. All entities may play multiple roles, including the SuD.

                                                                                                                                                  • 主要参与者通过使用 SuD 的服务实现了用户目标。例如,收银员。

                                                                                                                                                    • 为什么要识别?查找驱动用例的用户目标。

                                                                                                                                                  • Primary actor has user goals fulfilled through using services of the SuD. For example, the cashier.

                                                                                                                                                    • Why identify? To find user goals, which drive the use cases.

                                                                                                                                                  • Supporting actor 向 SuD 提供服务(例如,信息)。自动付款授权服务就是一个示例。通常是计算机系统,但可以是组织或个人。

                                                                                                                                                    • 为什么要识别?阐明外部接口和协议。

                                                                                                                                                  • Supporting actor provides a service (for example, information) to the SuD. The automated payment authorization service is an example. Often a computer system, but could be an organization or person.

                                                                                                                                                    • Why identify? To clarify external interfaces and protocols.

                                                                                                                                                  • 台下参与者对用例的行为感兴趣,但不是主要参与者或支持者;例如,政府税务机构。

                                                                                                                                                    • 为什么要识别?确保识别和满足所有必要的利益。除非明确指出这些演员,否则台下演员的兴趣有时是微妙的或容易被忽视的。

                                                                                                                                                  • Offstage actor has an interest in the behavior of the use case, but is not primary or supporting; for example, a government tax agency.

                                                                                                                                                    • Why identify? To ensure that all necessary interests are identified and satisfied. Offstage actor interests are sometimes subtle or easy to miss unless these actors are explicitly named.

                                                                                                                                                    6.7. 表示法:三种常见的用例格式是什么?

                                                                                                                                                    6.7. Notation: What are Three Common Use Case Formats?

                                                                                                                                                    用例可以采用不同的格式和正式程度编写:

                                                                                                                                                    Use cases can be written in different formats and levels of formality:

                                                                                                                                                    • 简短的一段总结,通常是主要的成功场景。前面的流程销售示例很简短。

                                                                                                                                                      例子63



                                                                                                                                                      • 什么时候?在早期需求分析期间,快速了解主题和范围。可能只需几分钟即可创建。

                                                                                                                                                    • brief Terse one-paragraph summary, usually of the main success scenario. The prior Process Sale example was brief.



                                                                                                                                                      • When? During early requirements analysis, to get a quick sense of subject and scope. May take only a few minutes to create.

                                                                                                                                                    • 休闲非正式段落格式。涵盖各种场景的多个段落。前面的 Handle Returns 示例是随意的。

                                                                                                                                                      例子63



                                                                                                                                                      • 什么时候?同上。

                                                                                                                                                    • casual Informal paragraph format. Multiple paragraphs that cover various scenarios. The prior Handle Returns example was casual.



                                                                                                                                                      • When? As above.

                                                                                                                                                    • 全副武装所有步骤和变体都详细编写,并且有支持部分,例如先决条件和成功保证。

                                                                                                                                                      例子68



                                                                                                                                                      • 什么时候?在确定了许多用例并以简短的格式编写之后,在第一次需求研讨会期间,将详细编写一些(例如 10%)具有架构重要性和高价值的用例。

                                                                                                                                                    • fully dressed All steps and variations are written in detail, and there are supporting sections, such as preconditions and success guarantees.



                                                                                                                                                      • When? After many use cases have been identified and written in a brief format, then during the first requirements workshop a few (such as 10%) of the architecturally significant and high-value use cases are written in detail.

                                                                                                                                                    更多关于编写 Timing of Writing 用例的信息,第 95

                                                                                                                                                    more on timing of writing use cases p. 95



                                                                                                                                                    以下示例是 NextGen 案例研究的全貌案例。

                                                                                                                                                    The following example is a fully dressed case for our NextGen case study.

                                                                                                                                                      6.8. 示例:流程销售,全装风格

                                                                                                                                                      6.8. Example: Process Sale, Fully Dressed Style

                                                                                                                                                      全装饰的用例显示更多细节并且结构清晰;他们挖掘得更深。

                                                                                                                                                      Fully dressed use cases show more detail and are structured; they dig deeper.

                                                                                                                                                      在迭代和进化的 UP 需求分析中,在第一次需求研讨会期间,10% 的关键用例将以这种方式编写。然后,设计和编程从这 10% 集合中最具架构意义的用例或场景开始。

                                                                                                                                                      In iterative and evolutionary UP requirements analysis, 10% of the critical use cases would be written this way during the first requirements workshop. Then design and programming starts on the most architecturally significant use cases or scenarios from that 10% set.

                                                                                                                                                      各种格式模板可用于详细的使用案例。自 1990 年代初以来,使用和共享最广泛的格式可能是 Web at alistair.cockburn.us 上提供的模板,该模板由 Alistair Cockburn 创建,他是最受欢迎的书籍和用例建模方法的作者。以下示例说明了此样式。

                                                                                                                                                      Various format templates are available for detailed use cases. Probably the most widely used and shared format, since the early 1990s, is the template available on the Web at alistair.cockburn.us, created by Alistair Cockburn, the author of the most popular book and approach to use-case modeling. The following example illustrates this style.

                                                                                                                                                      主要成功场景 和 扩展 是两个主要部分

                                                                                                                                                      Main Success Scenario and Extensions are the two major sections



                                                                                                                                                      首先,这是模板:

                                                                                                                                                      First, here's the template:

                                                                                                                                                      用例部分

                                                                                                                                                      Use Case Section

                                                                                                                                                      评论

                                                                                                                                                      Comment

                                                                                                                                                      用例名称

                                                                                                                                                      Use Case Name

                                                                                                                                                      以动词开头。

                                                                                                                                                      Start with a verb.

                                                                                                                                                      范围

                                                                                                                                                      Scope

                                                                                                                                                      正在设计的系统。

                                                                                                                                                      The system under design.

                                                                                                                                                      水平

                                                                                                                                                      Level

                                                                                                                                                      “用户目标”或“子功能”

                                                                                                                                                      "user-goal" or "subfunction"

                                                                                                                                                      主要参与者

                                                                                                                                                      Primary Actor

                                                                                                                                                      调用系统以交付其服务。

                                                                                                                                                      Calls on the system to deliver its services.

                                                                                                                                                      利益相关者和利益

                                                                                                                                                      Stakeholders and Interests

                                                                                                                                                      谁关心这个用例,他们想要什么?

                                                                                                                                                      Who cares about this use case, and what do they want?

                                                                                                                                                      前提 条件

                                                                                                                                                      Preconditions

                                                                                                                                                      什么在开始时必须是真实的,并且值得告诉读者?

                                                                                                                                                      What must be true on start, and worth telling the reader?

                                                                                                                                                      成功保证

                                                                                                                                                      Success Guarantee

                                                                                                                                                      成功完成时必须为真,值得告诉读者。

                                                                                                                                                      What must be true on successful completion, and worth telling the reader.

                                                                                                                                                      主要成功场景

                                                                                                                                                      Main Success Scenario

                                                                                                                                                      一个典型的、无条件的成功快乐之路情景。

                                                                                                                                                      A typical, unconditional happy path scenario of success.

                                                                                                                                                      扩展

                                                                                                                                                      Extensions

                                                                                                                                                      成功或失败的替代方案。

                                                                                                                                                      Alternate scenarios of success or failure.

                                                                                                                                                      特殊要求

                                                                                                                                                      Special Requirements

                                                                                                                                                      相关的非功能性要求。

                                                                                                                                                      Related non-functional requirements.

                                                                                                                                                      技术和数据变体列表

                                                                                                                                                      Technology and Data Variations List

                                                                                                                                                      不同的 I/O 方法和数据格式。

                                                                                                                                                      Varying I/O methods and data formats.

                                                                                                                                                      发生频率

                                                                                                                                                      Frequency of Occurrence

                                                                                                                                                      影响调查、测试和实施时间。

                                                                                                                                                      Influences investigation, testing, and timing of implementation.

                                                                                                                                                      杂项

                                                                                                                                                      Miscellaneous

                                                                                                                                                      例如未解决的问题。

                                                                                                                                                      Such as open issues.



                                                                                                                                                      下面是一个基于模板的示例。

                                                                                                                                                      Here's an example, based on the template.

                                                                                                                                                      请注意,这是本书详细用例的主要案例研究示例;它显示了许多常见的元素和问题。

                                                                                                                                                      Please note that this is the book's primary case study example of a detailed use case; it shows many common elements and issues.

                                                                                                                                                      它可能比您想知道的有关 POS 系统的更多信息要多得多!但是,它适用于真实的 POS,并展示了使用案例捕获复杂实际需求和深度分支场景的能力。

                                                                                                                                                      It probably shows much more than you ever wanted to know about a POS system! But, it's for a real POS, and shows the ability of use cases to capture complex real-world requirements, and deeply branching scenarios.



                                                                                                                                                      用例 UC1:流程销售

                                                                                                                                                      范围:NextGen POS 应用程序

                                                                                                                                                      Scope: NextGen POS application

                                                                                                                                                      级别:用户目标

                                                                                                                                                      Level: user goal

                                                                                                                                                      主要演员: 收银员

                                                                                                                                                      Primary Actor: Cashier

                                                                                                                                                      利益相关者和利益

                                                                                                                                                      Stakeholders and Interests:

                                                                                                                                                      - 收银员:想要准确、快速的输入,并且没有付款错误,因为现金抽屉短缺会从他/她的工资中扣除。



                                                                                                                                                      - Cashier: Wants accurate, fast entry, and no payment errors, as cash drawer shortages are deducted from his/her salary.



                                                                                                                                                      - Salesperson:希望更新销售佣金。



                                                                                                                                                      - Salesperson: Wants sales commissions updated.



                                                                                                                                                      - 客户:希望以最少的努力获得购买和快速服务。希望轻松显示输入的项目和价格。需要购买证明以支持退货。



                                                                                                                                                      - Customer: Wants purchase and fast service with minimal effort. Wants easily visible display of entered items and prices. Wants proof of purchase to support returns.



                                                                                                                                                      - 公司:希望准确记录交易并满足客户利益。希望确保记录 Payment Authorization Service 应收账款。需要一些容错能力,以便在服务器组件(例如,远程信用验证)不可用时也能捕获销售。希望自动快速更新会计和库存。



                                                                                                                                                      - Company: Wants to accurately record transactions and satisfy customer interests. Wants to ensure that Payment Authorization Service payment receivables are recorded. Wants some fault tolerance to allow sales capture even if server components (e.g., remote credit validation) are unavailable. Wants automatic and fast update of accounting and inventory.



                                                                                                                                                      - Manager:希望能够快速执行 override 操作,并轻松调试 Cashier 问题。



                                                                                                                                                      - Manager: Wants to be able to quickly perform override operations, and easily debug Cashier problems.



                                                                                                                                                      - 政府税务机构: 希望从每笔销售中收取税款。可以是多个机构,例如国家、州和县。



                                                                                                                                                      - Government Tax Agencies: Want to collect tax from every sale. May be multiple agencies, such as national, state, and county.



                                                                                                                                                      - Payment Authorization Service:希望以正确的格式和协议接收数字授权请求。想要准确核算他们向商店支付的应付账款。



                                                                                                                                                      - Payment Authorization Service: Wants to receive digital authorization requests in the correct format and protocol. Wants to accurately account for their payables to the store.



                                                                                                                                                      前提 条件:Cashier 被识别和验证。

                                                                                                                                                      Preconditions: Cashier is identified and authenticated.

                                                                                                                                                      成功保证(或后置条件):节省销售。税款计算正确。会计核算和库存已更新。记录的佣金。生成收据。记录付款授权批准。

                                                                                                                                                      Success Guarantee (or Postconditions): Sale is saved. Tax is correctly calculated. Accounting and Inventory are updated. Commissions recorded. Receipt is generated. Payment authorization approvals are recorded.

                                                                                                                                                      主要成功方案(或基本流程):

                                                                                                                                                      Main Success Scenario (or Basic Flow):

                                                                                                                                                      1. 客户到达 POS 收银台时,携带要购买的商品和/或服务。

                                                                                                                                                      2. Customer arrives at POS checkout with goods and/or services to purchase.

                                                                                                                                                      3. 出纳开始新的销售。

                                                                                                                                                      4. Cashier starts a new sale.

                                                                                                                                                      5. 收银员输入商品标识符。

                                                                                                                                                      6. Cashier enters item identifier.

                                                                                                                                                      7. 系统记录销售行项目并显示项目描述、价格和汇总。根据一组价格规则计算出的价格。

                                                                                                                                                        收银员重复步骤 3-4,直到指示完成。

                                                                                                                                                      8. System records sale line item and presents item description, price, and running total. Price calculated from a set of price rules.

                                                                                                                                                        Cashier repeats steps 3-4 until indicates done.

                                                                                                                                                      1. 系统显示计算税款的总额。

                                                                                                                                                      2. System presents total with taxes calculated.

                                                                                                                                                      3. 收银员告诉客户总数,并要求付款。

                                                                                                                                                      4. Cashier tells Customer the total, and asks for payment.

                                                                                                                                                      5. 客户付款,系统处理付款。

                                                                                                                                                      6. Customer pays and System handles payment.

                                                                                                                                                      7. 系统记录已完成的销售,并将销售和付款信息发送到外部会计系统(用于会计和佣金)和库存系统(用于更新库存)。

                                                                                                                                                      8. System logs completed sale and sends sale and payment information to the external Accounting system (for accounting and commissions) and Inventory system (to update inventory).

                                                                                                                                                      9. 系统出示收据。

                                                                                                                                                      10. System presents receipt.

                                                                                                                                                      11. 客户带着收据和货物(如果有)离开。

                                                                                                                                                      12. Customer leaves with receipt and goods (if any).

                                                                                                                                                      扩展 (或替代流):

                                                                                                                                                      Extensions (or Alternative Flows):

                                                                                                                                                      *一个。Manager 会随时请求覆盖操作:

                                                                                                                                                      1. 系统进入 Manager 授权模式。

                                                                                                                                                      2. Manager 或 Cashier 执行一个 Manager 模式操作。例如,现金余额变化、恢复另一个收银机上的暂停销售、取消销售等。

                                                                                                                                                      3. 系统将恢复为 Cashier 授权模式。

                                                                                                                                                      *b.在任何时候,系统都会失败:

                                                                                                                                                      为了支持恢复和正确记帐,请确保所有事务敏感状态和事件都可以从方案的任何步骤中恢复。

                                                                                                                                                      1. 收银员重新启动系统,登录并请求恢复之前的状态。

                                                                                                                                                      2. 系统重建以前的状态。

                                                                                                                                                        2a.系统检测到阻止恢复的异常:

                                                                                                                                                        1. 系统向收银员发出错误信号,记录错误,并进入干净状态。

                                                                                                                                                        2. 出纳开始新的销售。

                                                                                                                                                      1a.客户或经理指示恢复暂停的销售。

                                                                                                                                                      1. 收银员执行恢复操作,并输入 ID 以检索销售。

                                                                                                                                                      2. 系统显示已恢复销售的状态,并带有小计。

                                                                                                                                                        2a.未找到销售。

                                                                                                                                                        1. 系统向收银员发出错误信号。

                                                                                                                                                        2. 收银员可能会开始新的销售并重新输入所有项目。

                                                                                                                                                      3. 收银员继续销售(可能输入更多物品或处理付款)。

                                                                                                                                                      2-4a. 客户告诉收银员他们具有免税身份(例如,老年人、原住民)

                                                                                                                                                      1. 收银员验证,然后输入免税状态代码。

                                                                                                                                                      2. 系统记录状态(将在税款计算期间使用)

                                                                                                                                                      3a.无效的商品 ID(在系统中找不到):

                                                                                                                                                      1. 系统发出错误信号并拒绝入场。

                                                                                                                                                      2. 收银员对错误做出回应:

                                                                                                                                                      2a.有一个人类可读的商品 ID(例如,数字 UPC):

                                                                                                                                                      1. 收银员手动输入项目 ID。

                                                                                                                                                      2. 系统显示描述和价格。

                                                                                                                                                      2a.商品 ID 无效: 系统信号错误。收银员尝试其他方法。

                                                                                                                                                      2b.没有商品 ID,但标签上有价格:

                                                                                                                                                      1. 出纳要求 Manager 执行覆盖操作。

                                                                                                                                                      2. Managers 执行 override。

                                                                                                                                                      3. 出纳指示手动输入价格,输入价格,并请求对此金额进行标准征税(因为没有产品信息,所以税务引擎无法推断如何对其进行征税)

                                                                                                                                                      2c.收银员执行“查找产品帮助”以获取真实的商品 ID 和价格。

                                                                                                                                                      2d. 否则,收银员会要求员工提供真实的商品 ID 或价格,然后手动 ID 或手动输入价格(见上文)。

                                                                                                                                                      3b.存在多个相同的商品分类,并且追踪唯一商品身份并不重要(例如,5 包素食汉堡):

                                                                                                                                                      1. 收银员可以输入商品类别标识符和数量。

                                                                                                                                                      3c.商品需要手动输入分类和价格(例如鲜花或带有价格的卡片):

                                                                                                                                                      1. 出纳 输入特殊手册类别代码加上价格。

                                                                                                                                                      3-6a:顾客要求收银员从购买的商品中移除(即作废):

                                                                                                                                                      仅当商品值小于收银员的 void 限制时,这才是合法的,否则需要 Manager 覆盖。

                                                                                                                                                      1. 收银员输入要从销售中删除的项目标识符。

                                                                                                                                                      2. 系统删除项目并显示更新的运行总计。

                                                                                                                                                        2a.商品价格超过收银员的无效限制:

                                                                                                                                                        1. 系统发出错误信号,并建议 Manager 覆盖。

                                                                                                                                                        2. 收银员请求 Manager override,获取它,然后重复操作。

                                                                                                                                                      3-6b. 客户告诉收银员取消销售:

                                                                                                                                                      1. 收银员取消了 System 上的销售。

                                                                                                                                                      3-6c. 收银员暂停销售:

                                                                                                                                                      1. 系统记录销售,以便可在任何 POS 收银机上检索。

                                                                                                                                                      2. 系统会显示一个“暂停收据”,其中包括行项目,以及用于检索和恢复销售的销售 ID。

                                                                                                                                                      4a.不需要系统提供的商品价格(例如,客户抱怨某事并获得了更低的价格):

                                                                                                                                                      1. 收银员请求经理批准。

                                                                                                                                                      2. Manager 执行覆盖操作。

                                                                                                                                                      3. 出纳输入手动覆盖价格。

                                                                                                                                                      4. 系统提供新价格。

                                                                                                                                                      5a.系统检测到无法与外部税务计算系统服务通信:

                                                                                                                                                      1. 系统在 POS 节点上重新启动服务,然后继续。

                                                                                                                                                        1a.系统检测到服务未重启。

                                                                                                                                                        1. 系统信号错误。

                                                                                                                                                        2. 出纳可以手动计算并输入税款,或取消销售。

                                                                                                                                                      5b.买家表示他们有资格享受折扣(例如,员工、优先顾客):

                                                                                                                                                      1. 收银员发出 discount 请求信号。

                                                                                                                                                      2. 收银员 输入 Customer identification。

                                                                                                                                                      3. 系统根据折扣规则显示折扣总额。

                                                                                                                                                      5c.客户表示他们的账户中有信用额度,可以申请销售:

                                                                                                                                                      1. 收银员发出信用请求信号。

                                                                                                                                                      2. 收银员 输入 Customer identification。

                                                                                                                                                      3. 系统应用积分,最高可达 price=0,并减少剩余积分。

                                                                                                                                                      6a.客户表示他们打算用现金付款,但没有足够的现金:

                                                                                                                                                      1. 收银员要求提供其他付款方式。

                                                                                                                                                        1a.客户告诉 Cashier 取消销售。收银员取消了 System 上的销售。

                                                                                                                                                      7a.现金支付:

                                                                                                                                                      1. 出纳输入支付的现金金额。

                                                                                                                                                      2. 系统显示到期余额,并释放银箱。

                                                                                                                                                      3. 出纳将现金存入客户,并将余额退还给客户。

                                                                                                                                                      4. 系统记录现金支付。

                                                                                                                                                      7b.通过信用卡支付:

                                                                                                                                                      1. 客户输入其信用账户信息。

                                                                                                                                                      2. 系统显示他们的付款以供验证。

                                                                                                                                                      3. 收银员确认道。

                                                                                                                                                        3a.收银员取消付款步骤:

                                                                                                                                                        1. 系统恢复为 “item entry” 模式。

                                                                                                                                                      4. 系统向外部 Payment Authorization Service System 发送支付授权请求,并请求支付审批。

                                                                                                                                                        4a.系统检测到与外部系统协作失败:

                                                                                                                                                        1. 系统向收银员发出错误信号。

                                                                                                                                                        2. 收银员要求客户进行替代付款。

                                                                                                                                                      5. 系统收到付款批准,向收银员发出批准信号,并释放收银机(以插入已签名的贷方付款收据)。

                                                                                                                                                        5a.系统收到付款被拒:

                                                                                                                                                        1. 系统向收银员发出拒绝信号。

                                                                                                                                                        2. 收银员要求客户进行替代付款。

                                                                                                                                                        5b.等待响应超时。

                                                                                                                                                        1. 系统向收银员发出超时信号。

                                                                                                                                                        2. 收银员可以重试,或要求 Customer 进行替代付款。

                                                                                                                                                      6. 系统记录贷方付款,其中包括付款审批。

                                                                                                                                                      7. 系统提供信用支付签名输入机制。

                                                                                                                                                      8. 收银员要求 Customer 提供信用付款签名。客户输入签名。

                                                                                                                                                      9. 如果在纸质收据上签名,收银员将收据放入现金抽屉并关闭。

                                                                                                                                                      7c.通过支票付款...

                                                                                                                                                      7d.通过借记卡付款...

                                                                                                                                                      7e.收银员取消付款步骤:

                                                                                                                                                      1. 系统恢复为 “item entry” 模式。

                                                                                                                                                      7f.客户赠送优惠券:

                                                                                                                                                      1. 在处理付款之前,收银员会记录每张优惠券,系统会适当降价。出于会计原因,系统记录已使用的优惠券。

                                                                                                                                                        1a.输入的优惠券不适用于任何购买的商品:

                                                                                                                                                        1. 系统向收银员发出错误信号。

                                                                                                                                                      9a.有产品返利:

                                                                                                                                                      1. 系统显示每个具有返利的物料的返利表单和返利收据。

                                                                                                                                                      9b.买家要求提供礼品收据(价格不可见):

                                                                                                                                                      1. 收银员要求提供礼品收据,系统出示礼品收据。

                                                                                                                                                      9c.打印机缺纸。

                                                                                                                                                      1. 如果系统可以检测到故障,则会发出问题信号。

                                                                                                                                                      2. 收银员取代纸张。

                                                                                                                                                      3. 收银员要求另一张收据。

                                                                                                                                                      *a. At any time, Manager requests an override operation:

                                                                                                                                                      1. System enters Manager-authorized mode.

                                                                                                                                                      2. Manager or Cashier performs one Manager-mode operation. e.g., cash balance change, resume a suspended sale on another register, void a sale, etc.

                                                                                                                                                      3. System reverts to Cashier-authorized mode.

                                                                                                                                                      *b. At any time, System fails:

                                                                                                                                                      To support recovery and correct accounting, ensure all transaction sensitive state and events can be recovered from any step of the scenario.

                                                                                                                                                      1. Cashier restarts System, logs in, and requests recovery of prior state.

                                                                                                                                                      2. System reconstructs prior state.

                                                                                                                                                        2a. System detects anomalies preventing recovery:

                                                                                                                                                        1. System signals error to the Cashier, records the error, and enters a clean state.

                                                                                                                                                        2. Cashier starts a new sale.

                                                                                                                                                      1a. Customer or Manager indicate to resume a suspended sale.

                                                                                                                                                      1. Cashier performs resume operation, and enters the ID to retrieve the sale.

                                                                                                                                                      2. System displays the state of the resumed sale, with subtotal.

                                                                                                                                                        2a. Sale not found.

                                                                                                                                                        1. System signals error to the Cashier.

                                                                                                                                                        2. Cashier probably starts new sale and re-enters all items.

                                                                                                                                                      3. Cashier continues with sale (probably entering more items or handling payment).

                                                                                                                                                      2-4a. Customer tells Cashier they have a tax-exempt status (e.g., seniors, native peoples)

                                                                                                                                                      1. Cashier verifies, and then enters tax-exempt status code.

                                                                                                                                                      2. System records status (which it will use during tax calculations)

                                                                                                                                                      3a. Invalid item ID (not found in system):

                                                                                                                                                      1. System signals error and rejects entry.

                                                                                                                                                      2. Cashier responds to the error:

                                                                                                                                                      2a. There is a human-readable item ID (e.g., a numeric UPC):

                                                                                                                                                      1. Cashier manually enters the item ID.

                                                                                                                                                      2. System displays description and price.

                                                                                                                                                      2a. Invalid item ID: System signals error. Cashier tries alternate method.

                                                                                                                                                      2b. There is no item ID, but there is a price on the tag:

                                                                                                                                                      1. Cashier asks Manager to perform an override operation.

                                                                                                                                                      2. Managers performs override.

                                                                                                                                                      3. Cashier indicates manual price entry, enters price, and requests standard taxation for this amount (because there is no product information, the tax engine can't otherwise deduce how to tax it)

                                                                                                                                                      2c. Cashier performs Find Product Help to obtain true item ID and price.

                                                                                                                                                      2d. Otherwise, Cashier asks an employee for the true item ID or price, and does either manual ID or manual price entry (see above).

                                                                                                                                                      3b. There are multiple of same item category and tracking unique item identity not important (e.g., 5 packages of veggie-burgers):

                                                                                                                                                      1. Cashier can enter item category identifier and the quantity.

                                                                                                                                                      3c. Item requires manual category and price entry (such as flowers or cards with a price on them):

                                                                                                                                                      1. Cashier enters special manual category code, plus the price.

                                                                                                                                                      3-6a: Customer asks Cashier to remove (i.e., void) an item from the purchase:

                                                                                                                                                      This is only legal if the item value is less than the void limit for Cashiers, otherwise a Manager override is needed.

                                                                                                                                                      1. Cashier enters item identifier for removal from sale.

                                                                                                                                                      2. System removes item and displays updated running total.

                                                                                                                                                        2a. Item price exceeds void limit for Cashiers:

                                                                                                                                                        1. System signals error, and suggests Manager override.

                                                                                                                                                        2. Cashier requests Manager override, gets it, and repeats operation.

                                                                                                                                                      3-6b. Customer tells Cashier to cancel sale:

                                                                                                                                                      1. Cashier cancels sale on System.

                                                                                                                                                      3-6c. Cashier suspends the sale:

                                                                                                                                                      1. System records sale so that it is available for retrieval on any POS register.

                                                                                                                                                      2. System presents a "suspend receipt" that includes the line items, and a sale ID used to retrieve and resume the sale.

                                                                                                                                                      4a. The system supplied item price is not wanted (e.g., Customer complained about something and is offered a lower price):

                                                                                                                                                      1. Cashier requests approval from Manager.

                                                                                                                                                      2. Manager performs override operation.

                                                                                                                                                      3. Cashier enters manual override price.

                                                                                                                                                      4. System presents new price.

                                                                                                                                                      5a. System detects failure to communicate with external tax calculation system service:

                                                                                                                                                      1. System restarts the service on the POS node, and continues.

                                                                                                                                                        1a. System detects that the service does not restart.

                                                                                                                                                        1. System signals error.

                                                                                                                                                        2. Cashier may manually calculate and enter the tax, or cancel the sale.

                                                                                                                                                      5b. Customer says they are eligible for a discount (e.g., employee, preferred customer):

                                                                                                                                                      1. Cashier signals discount request.

                                                                                                                                                      2. Cashier enters Customer identification.

                                                                                                                                                      3. System presents discount total, based on discount rules.

                                                                                                                                                      5c. Customer says they have credit in their account, to apply to the sale:

                                                                                                                                                      1. Cashier signals credit request.

                                                                                                                                                      2. Cashier enters Customer identification.

                                                                                                                                                      3. Systems applies credit up to price=0, and reduces remaining credit.

                                                                                                                                                      6a. Customer says they intended to pay by cash but don't have enough cash:

                                                                                                                                                      1. Cashier asks for alternate payment method.

                                                                                                                                                        1a. Customer tells Cashier to cancel sale. Cashier cancels sale on System.

                                                                                                                                                      7a. Paying by cash:

                                                                                                                                                      1. Cashier enters the cash amount tendered.

                                                                                                                                                      2. System presents the balance due, and releases the cash drawer.

                                                                                                                                                      3. Cashier deposits cash tendered and returns balance in cash to Customer.

                                                                                                                                                      4. System records the cash payment.

                                                                                                                                                      7b. Paying by credit:

                                                                                                                                                      1. Customer enters their credit account information.

                                                                                                                                                      2. System displays their payment for verification.

                                                                                                                                                      3. Cashier confirms.

                                                                                                                                                        3a. Cashier cancels payment step:

                                                                                                                                                        1. System reverts to "item entry" mode.

                                                                                                                                                      4. System sends payment authorization request to an external Payment Authorization Service System, and requests payment approval.

                                                                                                                                                        4a. System detects failure to collaborate with external system:

                                                                                                                                                        1. System signals error to Cashier.

                                                                                                                                                        2. Cashier asks Customer for alternate payment.

                                                                                                                                                      5. System receives payment approval, signals approval to Cashier, and releases cash drawer (to insert signed credit payment receipt).

                                                                                                                                                        5a. System receives payment denial:

                                                                                                                                                        1. System signals denial to Cashier.

                                                                                                                                                        2. Cashier asks Customer for alternate payment.

                                                                                                                                                        5b. Timeout waiting for response.

                                                                                                                                                        1. System signals timeout to Cashier.

                                                                                                                                                        2. Cashier may try again, or ask Customer for alternate payment.

                                                                                                                                                      6. System records the credit payment, which includes the payment approval.

                                                                                                                                                      7. System presents credit payment signature input mechanism.

                                                                                                                                                      8. Cashier asks Customer for a credit payment signature. Customer enters signature.

                                                                                                                                                      9. If signature on paper receipt, Cashier places receipt in cash drawer and closes it.

                                                                                                                                                      7c. Paying by check…

                                                                                                                                                      7d. Paying by debit…

                                                                                                                                                      7e. Cashier cancels payment step:

                                                                                                                                                      1. System reverts to "item entry" mode.

                                                                                                                                                      7f. Customer presents coupons:

                                                                                                                                                      1. Before handling payment, Cashier records each coupon and System reduces price as appropriate. System records the used coupons for accounting reasons.

                                                                                                                                                        1a. Coupon entered is not for any purchased item:

                                                                                                                                                        1. System signals error to Cashier.

                                                                                                                                                      9a. There are product rebates:

                                                                                                                                                      1. System presents the rebate forms and rebate receipts for each item with a rebate.

                                                                                                                                                      9b. Customer requests gift receipt (no prices visible):

                                                                                                                                                      1. Cashier requests gift receipt and System presents it.

                                                                                                                                                      9c. Printer out of paper.

                                                                                                                                                      1. If System can detect the fault, will signal the problem.

                                                                                                                                                      2. Cashier replaces paper.

                                                                                                                                                      3. Cashier requests another receipt.

                                                                                                                                                      特殊要求:

                                                                                                                                                      Special Requirements:

                                                                                                                                                      - 大型平板显示器上的触摸屏 UI。文本必须在 1 米外可见。

                                                                                                                                                      - Touch screen UI on a large flat panel monitor. Text must be visible from 1 meter.

                                                                                                                                                      - 在 90% 的时间内在 30 秒内完成积分授权响应。

                                                                                                                                                      - Credit authorization response within 30 seconds 90% of the time.

                                                                                                                                                      - 不知何故,我们希望在访问远程服务(如库存系统)失败时进行稳健的恢复。

                                                                                                                                                      - Somehow, we want robust recovery when access to remote services such the inventory system is failing.

                                                                                                                                                      - 显示的文本上的语言国际化。

                                                                                                                                                      - Language internationalization on the text displayed.

                                                                                                                                                      - 可在步骤 3 和 7 中插入可插入的可插拔业务规则。

                                                                                                                                                      - Pluggable business rules to be insertable at steps 3 and 7.

                                                                                                                                                      - …

                                                                                                                                                      - …

                                                                                                                                                      技术和数据变体列表:

                                                                                                                                                      Technology and Data Variations List:

                                                                                                                                                      *一个。通过读卡器滑动覆盖卡或通过键盘输入授权码来输入的 Manager override。

                                                                                                                                                      3a.通过条形码激光扫描仪(如果存在条形码)或键盘输入的项目标识符。

                                                                                                                                                      3b.商品编码可以是任何 UPC、EAN、JAN 或 SKU 编码方案。

                                                                                                                                                      7a.通过读卡器或键盘输入的信用账户信息。

                                                                                                                                                      7b.在纸质收据上捕获的信用付款签名。但两年内,我们预测许多客户将需要数字签名捕获。

                                                                                                                                                      *a. Manager override entered by swiping an override card through a card reader, or entering an authorization code via the keyboard.

                                                                                                                                                      3a. Item identifier entered by bar code laser scanner (if bar code is present) or keyboard.

                                                                                                                                                      3b. Item identifier may be any UPC, EAN, JAN, or SKU coding scheme.

                                                                                                                                                      7a. Credit account information entered by card reader or keyboard.

                                                                                                                                                      7b. Credit payment signature captured on paper receipt. But within two years, we predict many customers will want digital signature capture.

                                                                                                                                                      发生频率:可能几乎是连续的。

                                                                                                                                                      Frequency of Occurrence: Could be nearly continuous.

                                                                                                                                                      未解决的问题

                                                                                                                                                      Open Issues:

                                                                                                                                                      - 税法有哪些变化?

                                                                                                                                                      - What are the tax law variations?

                                                                                                                                                      - 探索远程服务恢复问题。

                                                                                                                                                      - Explore the remote service recovery issue.

                                                                                                                                                      - 不同的企业需要哪些定制?

                                                                                                                                                      - What customization is needed for different businesses?

                                                                                                                                                      - 收银员在注销时必须拿走他们的钱箱吗?

                                                                                                                                                      - Must a cashier take their cash drawer when they log out?

                                                                                                                                                      - 客户可以直接使用读卡器吗,还是必须由收银员来做?

                                                                                                                                                      - Can the customer directly use the card reader, or does the cashier have to do it?



                                                                                                                                                      此用例是说明性的,而不是详尽的(尽管它基于真实的 POS 系统需求,使用 Java 中的 OO 设计开发)。尽管如此,这里有足够的细节和复杂性来提供一种真实的感觉,即一个完整的用例可以记录许多需求细节。此示例将很好地用作许多用例问题的模型。

                                                                                                                                                      This use case is illustrative rather than exhaustive (although it is based on a real POS system's requirementsdeveloped with an OO design in Java). Nevertheless, there is enough detail and complexity here to offer a realistic sense that a fully dressed use case can record many requirement details. This example will serve well as a model for many use case problems.

                                                                                                                                                        6.9. 各部分是什么意思?

                                                                                                                                                        6.9. What do the Sections Mean?

                                                                                                                                                        前言元素

                                                                                                                                                        Preface Elements

                                                                                                                                                        范围

                                                                                                                                                        范围限制了正在设计的系统(或多个系统)。通常,用例描述使用一个软件(或硬件加软件)系统;在这种情况下,它被称为系统用例。在更广泛的范围内,使用案例还可以描述客户和合作伙伴如何使用企业。这样的企业级流程描述称为业务使用案例,是应用案例广泛适用的一个很好的示例,但本介绍性书籍中没有介绍它们。

                                                                                                                                                        The scope bounds the system (or systems) under design. Typically, a use case describes use of one software (or hardware plus software) system; in this case it is known as a system use case. At a broader scope, use cases can also describe how a business is used by its customers and partners. Such an enterprise-level process description is called a business use case and is a good example of the wide applicability of use cases, but they aren't covered in this introductory book.

                                                                                                                                                        水平

                                                                                                                                                        在 Cockburn 的系统中,用例分为用户目标级别或子功能级别等。用户目标级别用例是描述实现主要参与者完成工作目标的场景的常见类型;它大致对应于业务流程工程中的基本业务流程 (EBP)。子函数级使用案例描述支持用户目标所需的子步骤,通常创建子步骤以分解出多个常规使用案例共享的重复子步骤(以避免重复常见文本);一个例子是子函数使用案例 Pay by Credit ,许多常规使用案例都可以共享该案例。

                                                                                                                                                        In Cockburn's system, use cases are classified as at the user-goal level or the subfunction level, among others. A user-goal level use case is the common kind that describe the scenarios to fulfill the goals of a primary actor to get work done; it roughly corresponds to an elementary business process (EBP) in business process engineering. A subfunction-level use case describes substeps required to support a user goal, and is usually created to factor out duplicate substeps shared by several regular use cases (to avoid duplicating common text); an example is the subfunction use case Pay by Credit, which could be shared by many regular use cases.

                                                                                                                                                        EBP88

                                                                                                                                                        EBP p. 88



                                                                                                                                                        有关子函数用例的更多信息,请参阅用例“包含”关系,第 494

                                                                                                                                                        see the use case "include" relationship for more on subfunction use cases p. 494



                                                                                                                                                        主要参与者

                                                                                                                                                        调用系统服务来实现目标的主要参与者。

                                                                                                                                                        The principal actor that calls upon system services to fulfill a goal.

                                                                                                                                                        利益相关者和利益列表重要!

                                                                                                                                                        这个列表比乍一看更重要、更实用。它建议并限制了系统必须做什么。引用:

                                                                                                                                                        This list is more important and practical than may appear at first glance. It suggests and bounds what the system must do. To quote:

                                                                                                                                                        [系统] 在利益相关者之间运行一个合同,用例详细说明了该合同的行为部分......用例作为行为契约,捕获了与满足利益相关者利益相关的所有且仅与满足利益相关者利益相关的行为 [Cockburn01]。

                                                                                                                                                        The [system] operates a contract between stakeholders, with the use cases detailing the behavioral parts of that contract…The use case, as the contract for behavior, captures all and only the behaviors related to satisfying the stakeholders' interests [Cockburn01].

                                                                                                                                                        这回答了以下问题:用例中应该包含什么?答案是:满足所有利益相关者利益的方案。此外,在编写用例的其余部分之前,先从利益相关者及其利益开始,我们就有一种方法可以提醒我们系统更详细的职责应该是什么。例如,如果我没有首先列出销售人员利益相关者及其利益,我是否会确定销售人员佣金处理的责任?希望最终会,但也许我会在第一次分析会议中错过它。利益相关者利益视点为发现和记录所有必需的行为提供了一个全面而有条不紊的程序。

                                                                                                                                                        This answers the question: What should be in the use case? The answer is: That which satisfies all the stakeholders' interests. In addition, by starting with the stakeholders and their interests before writing the remainder of the use case, we have a method to remind us what the more detailed responsibilities of the system should be. For example, would I have identified a responsibility for salesperson commission handling if I had not first listed the salesperson stakeholder and their interests? Hopefully eventually, but perhaps I would have missed it during the first analysis session. The stakeholder interest viewpoint provides a thorough and methodical procedure for discovering and recording all the required behaviors.

                                                                                                                                                        利益相关者和利益

                                                                                                                                                        Stakeholders and Interests:

                                                                                                                                                        - 收银员:想要准确、快速的输入和没有付款错误,因为钱箱短缺会从他/她的工资中扣除。

                                                                                                                                                        - Cashier: Wants accurate, fast entry and no payment errors, as cash drawer shortages are deducted from his/her salary.

                                                                                                                                                        - Salesperson:希望更新销售佣金。

                                                                                                                                                        - Salesperson: Wants sales commissions updated.

                                                                                                                                                        - …

                                                                                                                                                        - …



                                                                                                                                                        前提条件和成功保证 (后置条件)

                                                                                                                                                        首先,不要为前提条件或成功保证而烦恼,除非你陈述了一些不明显且值得注意的事情,以帮助读者获得洞察力。不要在需求文档中添加无用的噪音。

                                                                                                                                                        First, don't bother with a precondition or success guarantee unless you are stating something non-obvious and noteworthy, to help the reader gain insight. Don't add useless noise to requirements documents.

                                                                                                                                                        前提条件规定了在用例中开始场景之前必须始终为 true 的内容。前提条件在用例中进行测试;相反,它们是假定为 true 的条件。通常,前提条件意味着已成功完成的另一个用例(例如登录)的场景。请注意,有些条件必须为 true,但不值得编写,例如 “the system has power”。前提条件传达了作者认为应该提醒读者的值得注意的假设。

                                                                                                                                                        Preconditions state what must always be true before a scenario is begun in the use case. Preconditions are not tested within the use case; rather, they are conditions that are assumed to be true. Typically, a precondition implies a scenario of another use case, such as logging in, that has successfully completed. Note that there are conditions that must be true, but are not worth writing, such as "the system has power." Preconditions communicate noteworthy assumptions that the writer thinks readers should be alerted to.

                                                                                                                                                        成功保证(或后置条件)规定了成功完成用例时必须为 true 的内容:主要成功场景或某些替代路径。保证应满足所有利益相关者的需求。

                                                                                                                                                        Success guarantees (or postconditions) state what must be true on successful completion of the use caseeither the main success scenario or some alternate path. The guarantee should meet the needs of all stakeholders.

                                                                                                                                                        前提 条件:Cashier 被识别和验证。

                                                                                                                                                        Preconditions: Cashier is identified and authenticated.

                                                                                                                                                        成功保证 (后置条件):节省销售。税款计算正确。会计核算和库存已更新。记录的佣金。生成收据。

                                                                                                                                                        Success Guarantee (Postconditions): Sale is saved. Tax is correctly calculated. Accounting and Inventory are updated. Commissions recorded. Receipt is generated.



                                                                                                                                                        主要成功场景和步骤(或基本流程)

                                                                                                                                                        Main Success Scenario and Steps (or Basic Flow)

                                                                                                                                                        这也被称为 “快乐路径” 情景,或者更平淡无奇的 “基本流” 或 “典型流”。它描述了满足利益相关者利益的典型成功路径。请注意,它通常不包括任何条件或分支。虽然没有错误或非法,但可以说它更容易理解和扩展,以非常一致并将所有条件处理推迟到 扩展 部分。

                                                                                                                                                        This has also been called the "happy path" scenario, or the more prosaic "Basic Flow" or "Typical Flow." It describes a typical success path that satisfies the interests of the stakeholders. Note that it often does not include any conditions or branching. Although not wrong or illegal, it is arguably more comprehensible and extendible to be very consistent and defer all conditional handling to the Extensions section.

                                                                                                                                                        指引

                                                                                                                                                        Guideline

                                                                                                                                                        将所有条件语句和分支语句推迟到 Extensions 部分。

                                                                                                                                                        Defer all conditional and branching statements to the Extensions section.



                                                                                                                                                        该方案记录了步骤,其中有三种类型:

                                                                                                                                                        The scenario records the steps, of which there are three kinds:

                                                                                                                                                        1. 参与者之间的交互。[3]

                                                                                                                                                          [3] 请注意,当所讨论的系统与其他系统合作时,它本身应该被视为一个参与者。

                                                                                                                                                        2. An interaction between actors.[3]

                                                                                                                                                          [3] Note that the system under discussion itself should be considered an actor when it plays an actor role collaborating with other systems.

                                                                                                                                                        3. 验证 (通常由系统) 验证。

                                                                                                                                                        4. A validation (usually by the system).

                                                                                                                                                        5. 系统的状态更改(例如,录制或修改某些内容)。

                                                                                                                                                        6. A state change by the system (for example, recording or modifying something).

                                                                                                                                                        用例的第一步并不总是属于此分类,但表示启动场景的触发器事件。

                                                                                                                                                        Step one of a use case does not always fall into this classification, but indicates the trigger event that starts the scenario.

                                                                                                                                                        为了便于识别,总是将演员的名字大写是一个常见的成语。还要注意用来表示重复的成语。

                                                                                                                                                        It is a common idiom to always capitalize the actors' names for ease of identification. Observe also the idiom that is used to indicate repetition.

                                                                                                                                                        主要成功情境

                                                                                                                                                        Main Success Scenario:

                                                                                                                                                        1. 客户到达 POS 结账处,其中包含要购买的商品。

                                                                                                                                                        2. Customer arrives at a POS checkout with items to purchase.

                                                                                                                                                        3. 出纳开始新的销售。

                                                                                                                                                        4. Cashier starts a new sale.

                                                                                                                                                        5. 收银员输入商品标识符。

                                                                                                                                                        6. Cashier enters item identifier.

                                                                                                                                                        收银员重复步骤 3-4,直到指示完成。

                                                                                                                                                        Cashier repeats steps 3-4 until indicates done.



                                                                                                                                                        扩展 (或备用流)

                                                                                                                                                        Extensions (or Alternate Flows)

                                                                                                                                                        扩展很重要,通常占文本的大部分。它们指示所有其他方案或分支,包括成功和失败。在全副武装的示例中,可以看到 Extensions 部分比 Main Success Scenario 部分长得多,也更复杂;这很常见。

                                                                                                                                                        Extensions are important and normally comprise the majority of the text. They indicate all the other scenarios or branches, both success and failure. Observe in the fully dressed example that the Extensions section was considerably longer and more complex than the Main Success Scenario section; this is common.

                                                                                                                                                        在详尽的用例编写中,快乐路径和扩展场景的组合应该满足“几乎”利益相关者的所有利益。这一点是有限制的,因为某些利益最好被描述为补充规范中表达的非功能性需求,而不是用例中表达的需求。例如,客户对可见的描述和价格感兴趣是一项可用性要求。

                                                                                                                                                        In thorough use case writing, the combination of the happy path and extension scenarios should satisfy "nearly" all the interests of the stakeholders. This point is qualified, because some interests may best be captured as non-functional requirements expressed in the Supplementary Specification rather than the use cases. For example, the customer's interest for a visible display of descriptions and prices is a usability requirement.

                                                                                                                                                        扩展方案是主要成功方案的分支,因此可以针对其步骤 1...N.例如,在主要成功方案的步骤 3 中,可能存在无效的项目标识符,这可能是因为它输入错误或系统未知。扩展标记为 “3a”;它首先标识条件,然后标识响应。步骤 3 中的备用扩展标记为“3b”,依此类推。

                                                                                                                                                        Extension scenarios are branches from the main success scenario, and so can be notated with respect to its steps 1…N. For example, at Step 3 of the main success scenario there may be an invalid item identifier, either because it was incorrectly entered or unknown to the system. An extension is labeled "3a"; it first identifies the condition and then the response. Alternate extensions at Step 3 are labeled "3b" and so forth.

                                                                                                                                                        扩展:

                                                                                                                                                        Extensions:

                                                                                                                                                        3a.标识符无效:

                                                                                                                                                        1. 系统发出错误信号并拒绝进入。

                                                                                                                                                        3b.存在多个相同的商品分类,并且追踪唯一商品身份并不重要(例如,5 包素食汉堡):

                                                                                                                                                        1. 收银员可以输入商品类别标识符和数量。

                                                                                                                                                        3a. Invalid identifier:

                                                                                                                                                        1. System signals error and rejects entry.

                                                                                                                                                        3b. There are multiple of same item category and tracking unique item identity not important (e.g., 5 packages of veggie-burgers):

                                                                                                                                                        1. Cashier can enter item category identifier and the quantity.



                                                                                                                                                        扩展由两部分组成:条件和处理。

                                                                                                                                                        An extension has two parts: the condition and the handling.

                                                                                                                                                        指引:如果可能,请将条件编写为系统或参与者可以检测到的内容。对比:

                                                                                                                                                        Guideline: When possible, write the condition as something that can be detected by the system or an actor. To contrast:

                                                                                                                                                        5a.系统检测到无法与外部税务计算系统服务通信:

                                                                                                                                                        5a.外部税款计算系统不工作:

                                                                                                                                                        5a. System detects failure to communicate with external tax calculation system service:

                                                                                                                                                        5a. External tax calculation system not working:

                                                                                                                                                        首选前一种样式,因为这是系统可以检测到的内容;后者是一个推论。

                                                                                                                                                        The former style is preferred because this is something the system can detect; the latter is an inference.

                                                                                                                                                        扩展处理可以总结为一个步骤,也可以包括一个序列,如以下示例所示,它还说明了表示法,以指示条件可以在一系列步骤中出现:

                                                                                                                                                        Extension handling can be summarized in one step, or include a sequence, as in this example, which also illustrates notation to indicate that a condition can arise within a range of steps:

                                                                                                                                                        3-6a: 客户要求收银员从购买中删除商品:

                                                                                                                                                        1. 收银员输入要从销售中删除的商品标识符。

                                                                                                                                                        2. 系统显示更新的运行总计。

                                                                                                                                                        3-6a: Customer asks Cashier to remove an item from the purchase:

                                                                                                                                                        1. Cashier enters the item identifier for removal from the sale.

                                                                                                                                                        2. System displays updated running total.



                                                                                                                                                        在扩展处理结束时,默认情况下,该方案将与主要成功方案合并,除非扩展另有指示(例如通过停止系统)。

                                                                                                                                                        At the end of extension handling, by default the scenario merges back with the main success scenario, unless the extension indicates otherwise (such as by halting the system).

                                                                                                                                                        有时,特定的扩展点非常复杂,例如“通过信用支付”扩展。这可能是将扩展表示为单独用例的动机。

                                                                                                                                                        Sometimes, a particular extension point is quite complex, as in the "paying by credit" extension. This can be a motivation to express the extension as a separate use case.

                                                                                                                                                        此扩展示例还演示了在扩展中表示失败的表示法。

                                                                                                                                                        This extension example also demonstrates the notation to express failures within extensions.

                                                                                                                                                        7b.通过信用卡支付:

                                                                                                                                                        1. 客户输入其信用账户信息。

                                                                                                                                                        2. 系统向外部 Payment Authorization Service System 发送支付授权请求,并请求支付审批。

                                                                                                                                                          2a.系统检测到与外部系统协作失败:

                                                                                                                                                          1. 系统向收银员发出错误信号。

                                                                                                                                                          2. 收银员要求客户进行替代付款。

                                                                                                                                                        7b. Paying by credit:

                                                                                                                                                        1. Customer enters their credit account information.

                                                                                                                                                        2. System sends payment authorization request to an external Payment Authorization Service System, and requests payment approval.

                                                                                                                                                          2a. System detects failure to collaborate with external system:

                                                                                                                                                          1. System signals error to Cashier.

                                                                                                                                                          2. Cashier asks Customer for alternate payment.



                                                                                                                                                        如果希望在任何(或至少大多数)步骤中尽可能描述扩展条件,则可以使用标签 *a、*b、...。

                                                                                                                                                        If it is desirable to describe an extension condition as possible during any (or at least most) steps, the labels *a, *b, …, can be used.

                                                                                                                                                        *一个。系统崩溃时:

                                                                                                                                                        为了支持恢复和正确记帐,请确保所有事务敏感状态和事件都可以在场景中的任何步骤恢复。

                                                                                                                                                        1. 收银员重新启动系统,登录并请求恢复之前的状态。

                                                                                                                                                        2. 系统重建以前的状态。

                                                                                                                                                        *a. At any time, System crashes:

                                                                                                                                                        In order to support recovery and correct accounting, ensure all transaction sensitive state and events can be recovered at any step in the scenario.

                                                                                                                                                        1. Cashier restarts the System, logs in, and requests recovery of prior state.

                                                                                                                                                        2. System reconstructs prior state.



                                                                                                                                                        执行另一个用例场景

                                                                                                                                                        有时,一个用例会分支以执行另一个用例场景。例如,故事 Find Product Help(用于显示产品详细信息,如描述、价格、图片或视频等)是一个不同的用例,有时会在 Process Sale 中执行(通常在找不到项目 ID 时)。在 Cockburn 表示法中,执行第二个用例时带有下划线,如下例所示:

                                                                                                                                                        Sometimes, a use case branches to perform another use case scenario. For example, the story Find Product Help (to show product details, such as description, price, a picture or video, and so on) is a distinct use case that is sometimes performed while within Process Sale (usually when the item ID can't be found). In Cockburn notation, performing this second use case is shown with underlining, as this example shows:

                                                                                                                                                        3a.无效的商品 ID(在系统中找不到):

                                                                                                                                                        1. 系统发出错误信号并拒绝入场。

                                                                                                                                                        2. 收银员对错误做出回应:

                                                                                                                                                        2a. ......

                                                                                                                                                        2c.收银员执行“查找产品帮助”以获取真实的商品 ID 和价格。

                                                                                                                                                        3a. Invalid item ID (not found in system):

                                                                                                                                                        1. System signals error and rejects entry.

                                                                                                                                                        2. Cashier responds to the error:

                                                                                                                                                        2a. …

                                                                                                                                                        2c. Cashier performs Find Product Help to obtain true item ID and price.



                                                                                                                                                        像往常一样,假设用例是使用超链接工具编写的,然后单击此带下划线的用例名称将显示其文本。

                                                                                                                                                        Assuming, as usual, that the use cases are written with a hyperlinking tool, then clicking on this underlined use case name will display its text.

                                                                                                                                                        特殊要求

                                                                                                                                                        Special Requirements

                                                                                                                                                        如果非功能性要求、质量属性或约束与用例特别相关,请将其与用例一起记录。这些因素包括性能、可靠性和可用性等品质,以及已强制要求或被认为可能的设计约束(通常在 I/O 设备中)。

                                                                                                                                                        If a non-functional requirement, quality attribute, or constraint relates specifically to a use case, record it with the use case. These include qualities such as performance, reliability, and usability, and design constraints (often in I/O devices) that have been mandated or considered likely.

                                                                                                                                                        特殊要求:

                                                                                                                                                        Special Requirements:

                                                                                                                                                        - 大型平板显示器上的触摸屏 UI。文本必须在 1 米外可见。

                                                                                                                                                        - Touch screen UI on a large flat panel monitor. Text must be visible from 1 meter.

                                                                                                                                                        - 在 90% 的时间内在 30 秒内完成积分授权响应。

                                                                                                                                                        - Credit authorization response within 30 seconds 90% of the time.

                                                                                                                                                        - 显示的文本上的语言国际化。

                                                                                                                                                        - Language internationalization on the text displayed.

                                                                                                                                                        - 在步骤 2 和 6 中插入可插入的可插拔业务规则。

                                                                                                                                                        - Pluggable business rules to be insertable at steps 2 and 6.



                                                                                                                                                        使用用例记录这些内容是经典的 UP 建议,也是首次编写使用案例时的合理位置。但是,许多从业者发现,为了内容管理、理解和可读性,最终将补充规范中的所有非功能性需求移动和合并是有用的,因为在架构分析期间,这些需求通常必须作为一个整体来考虑。

                                                                                                                                                        Recording these with the use case is classic UP advice, and a reasonable location when first writing the use case. However, many practitioners find it useful to ultimately move and consolidate all non-functional requirements in the Supplementary Specification, for content management, comprehension, and readability, because these requirements usually have to be considered as a whole during architectural analysis.

                                                                                                                                                        技术和数据变体列表

                                                                                                                                                        Technology and Data Variations List

                                                                                                                                                        通常,必须如何完成某事存在技术差异,但不会存在技术差异,值得注意的是,在用例中记录这一点。一个常见的例子是利益相关者对输入或输出技术施加的技术限制。例如,利益相关者可能会说,“POS 系统必须支持使用读卡器和键盘输入信用账户。请注意,这些是早期设计决策或约束的示例;一般来说,避免过早的设计决策是很巧妙的,但有时它们是显而易见的或不可避免的,尤其是关于输入/输出技术。

                                                                                                                                                        Often there are technical variations in how something must be done, but not what, and it is noteworthy to record this in the use case. A common example is a technical constraint imposed by a stakeholder regarding input or output technologies. For example, a stakeholder might say, "The POS system must support credit account input using a card reader and the keyboard." Note that these are examples of early design decisions or constraints; in general, it is skillful to avoid premature design decisions, but sometimes they are obvious or unavoidable, especially concerning input/output technologies.

                                                                                                                                                        还需要了解数据方案的变化,例如将 UPC 或 EAN 用于以条形码符号系统编码的项目标识符。

                                                                                                                                                        It is also necessary to understand variations in data schemes, such as using UPCs or EANs for item identifiers, encoded in bar code symbology.

                                                                                                                                                        恭喜:用例是写错的 (!

                                                                                                                                                        Congratulations: Use Cases are Written and Wrong (!)

                                                                                                                                                        NextGen POS 团队正在多个短期需求研讨会上编写一些用例,同时进行一系列涉及生产质量编程和测试的短时间限制开发迭代。该团队正在逐步添加到用例集,并根据早期编程、测试和演示的反馈进行改进和调整。主题专家、出纳和开发人员积极参与需求分析。

                                                                                                                                                        The NextGen POS team is writing a few use cases in multiple short requirements workshops, in parallel with a series of short timeboxed development iterations that involve production-quality programming and testing. The team is incrementally adding to the use case set, and refining and adapting based on feedback from early programming, tests, and demos. Subject matter experts, cashiers, and developers actively participate in requirements analysis.

                                                                                                                                                        这是一个很好的进化分析过程,而不是瀑布式的,但仍然需要一定程度的“需求现实主义”。书面规范和其他模型给人一种正确的错觉,但模型却撒谎(无意中)。只有代码和测试才能揭示真正需要和有效的真相。

                                                                                                                                                        That's a good evolutionary analysis processrather than the waterfallbut a dose of "requirements realism" is still needed. Written specifications and other models give the illusion of correctness, but models lie (unintentionally). Only code and tests reveals the truth of what's really wanted and works.

                                                                                                                                                        用例、UML 图等不会得到完美的保证。它们将缺乏关键信息并包含错误的陈述。解决方案不是试图在一开始就记录近乎完美和完整的规范的瀑布式态度,尽管我们当然会在可用的时间内尽我们所能,并且应该学习和应用伟大的需求实践。但这永远不够。

                                                                                                                                                        The use cases, UML diagrams, and so forth won't be perfectguaranteed. They will lack critical information and contain wrong statements. The solution is not the waterfall attitude of trying to record specifications near-perfect and complete at the startalthough of course we do the best we can in the time available, and should learn and apply great requirements practices. But it will never be enough.

                                                                                                                                                        这并不是在没有任何分析或建模的情况下匆忙编码。在瀑布式编程和临时编程之间有一条中间道路:迭代和进化开发。在这种方法中,用例和其他模型通过早期编程和测试逐步完善、验证和阐明。

                                                                                                                                                        This isn't a call to rush to coding without any analysis or modeling. There is a middle way, between the waterfall and ad hoc programming: iterative and evolutionary development. In this approach the use cases and other models are incrementally refined, verified, and clarified through early programming and testing.

                                                                                                                                                        如果团队试图在开始第一次开发迭代之前详细编写所有或大部分用例,或者相反,您就知道您走在了错误的道路上。

                                                                                                                                                        You know you're on the wrong path if the team tries to write in detail all or most of the use cases before beginning the first development iterationor the opposite.



                                                                                                                                                        此列表是记录此类变化的地方。记录可能在特定步骤捕获的数据中的差异也很有用。

                                                                                                                                                        This list is the place to record such variations. It is also useful to record variations in the data that may be captured at a particular step.

                                                                                                                                                        技术和数据变体列表:

                                                                                                                                                        Technology and Data Variations List:

                                                                                                                                                        3a.由激光扫描仪或键盘输入的项目标识符。

                                                                                                                                                        3b.商品编码可以是任何 UPC、EAN、JAN 或 SKU 编码方案。

                                                                                                                                                        7a.通过读卡器或键盘输入的信用账户信息。

                                                                                                                                                        7b.在纸质收据上捕获的信用付款签名。但两年内,我们预测许多客户将需要数字签名捕获。

                                                                                                                                                        3a. Item identifier entered by laser scanner or keyboard.

                                                                                                                                                        3b. Item identifier may be any UPC, EAN, JAN, or SKU coding scheme.

                                                                                                                                                        7a. Credit account information entered by card reader or keyboard.

                                                                                                                                                        7b. Credit payment signature captured on paper receipt. But within two years, we predict many customers will want digital signature capture.



                                                                                                                                                          6.10. 表示法:还有其他格式吗?双柱变体

                                                                                                                                                          6.10. Notation: Are There Other Formats? A Two-Column Variation

                                                                                                                                                          有些人更喜欢两列或对话格式,它强调参与者和系统之间的交互。它首先由 Rebecca Wirfs-Brock 在 [Wirfs-Brock93] 中提出,Constantine 和 Lockwood 也推广了它以帮助可用性分析和工程 [CL99]。以下是使用两列格式的相同内容:

                                                                                                                                                          Some prefer the two-column or conversational format, which emphasizes the interaction between the actors and the system. It was first proposed by Rebecca Wirfs-Brock in [Wirfs-Brock93], and is also promoted by Constantine and Lockwood to aid usability analysis and engineering [CL99]. Here is the same content using the two-column format:

                                                                                                                                                          用例 UC1:流程销售

                                                                                                                                                          主要参与者:...

                                                                                                                                                          Primary Actor:

                                                                                                                                                           

                                                                                                                                                          …如故。。。

                                                                                                                                                          … as before …

                                                                                                                                                           

                                                                                                                                                          主要成功情境

                                                                                                                                                          Main Success Scenario:

                                                                                                                                                           

                                                                                                                                                          参与者操作(或意图)

                                                                                                                                                          Actor Action (or Intention)

                                                                                                                                                          系统责任

                                                                                                                                                          System Responsibility

                                                                                                                                                          1.客户到达 POS 收银台,并携带要购买的商品和/或服务。

                                                                                                                                                          1.Customer arrives at a POS checkout with goods and/or services to purchase.

                                                                                                                                                           

                                                                                                                                                          2.收银员开始新的销售。

                                                                                                                                                          2.Cashier starts a new sale.

                                                                                                                                                           

                                                                                                                                                          3.收银员输入商品标识符。

                                                                                                                                                          3.Cashier enters item identifier.

                                                                                                                                                          4.记录每个销售行项目并显示项目描述和运行总计。

                                                                                                                                                          4.Records each sale line item and presents item description and running total.

                                                                                                                                                          收银员重复步骤 3-4,直到指示完成。

                                                                                                                                                          Cashier repeats steps 3-4 until indicates done.

                                                                                                                                                          5.显示计算税款的总额。

                                                                                                                                                          5.Presents total with taxes calculated.

                                                                                                                                                          6.收银员告诉客户总额,并要求付款。

                                                                                                                                                          6.Cashier tells Customer the total, and asks for payment.

                                                                                                                                                           

                                                                                                                                                          7.客户付费。

                                                                                                                                                          7.Customer pays.

                                                                                                                                                          8.处理付款。

                                                                                                                                                          8.Handles payment.

                                                                                                                                                           

                                                                                                                                                          9.记录已完成的销售,并将信息发送到外部会计(所有会计和佣金)和库存系统(以更新库存)。系统出示收据。

                                                                                                                                                          9.Logs the completed sale and sends information to the external accounting (for all accounting and commissions) and inventory systems (to update inventory). System presents receipt.



                                                                                                                                                          最好的格式?

                                                                                                                                                          The Best Format?

                                                                                                                                                          没有一种最好的格式;有些人喜欢单列样式,有些人喜欢两列样式。可以添加和删除部分;标题名称可能会更改。这些都不是特别重要的;关键是以某种形式编写主要成功场景及其扩展的详细信息。[Cockburn01] 总结了许多可用的格式。

                                                                                                                                                          There isn't one best format; some prefer the one-column style, some the two-column. Sections may be added and removed; heading names may change. None of this is particularly important; the key thing is to write the details of the main success scenario and its extensions, in some form. [Cockburn01] summarizes many usable formats.

                                                                                                                                                          个人实践

                                                                                                                                                          Personal Practice

                                                                                                                                                          这是我的做法,而不是建议。几年来,我一直使用两列格式,因为它在对话中具有明显的视觉分离。但是,我已经恢复为单列样式,因为它更紧凑且更易于格式化,并且视觉上分离的对话的微小价值对我来说并没有超过这些好处。我发现,如果每一方和系统响应通常都分配给他们自己的步骤,那么直观地识别对话中的不同方(客户、系统等)仍然很简单。

                                                                                                                                                          This is my practice, not a recommendation. For some years, I used the two-column format because of its clear visual separation in the conversation. However, I have reverted to a one-column style as it is more compact and easier to format, and the slight value of the visually separated conversation does not for me outweigh these benefits. I find it still simple to visually identify the different parties in the conversation (Customer, System, …) if each party and the System responses are usually allocated to their own steps.



                                                                                                                                                            6.11. 指南:以基本的无 UI 样式编写

                                                                                                                                                            6.11. Guideline: Write in an Essential UI-Free Style

                                                                                                                                                            新的和改进的!指纹识别案例

                                                                                                                                                            New and Improved! The Case for Fingerprinting

                                                                                                                                                            在需求研讨会期间,收银员可能会说他的目标之一是 “登录”。收银员可能正在考虑 GUI、对话框、用户 ID 和密码。这是一种实现目标的机制,而不是目标本身。通过调查目标层次结构(“那个目标的目标是什么?”),系统分析师得出了一个独立于机制的目标:“识别自己并进行身份验证”,或者一个更高的目标:“防止盗窃......”。

                                                                                                                                                            During a requirements workshop, the cashier may say one of his goals is to "log in." The cashier was probably thinking of a GUI, dialog box, user ID, and password. This is a mechanism to achieve a goal, rather than the goal itself. By investigating up the goal hierarchy ("What is the goal of that goal?"), the system analyst arrives at a mechanism-independent goal: "identify myself and get authenticated," or an even higher goal: "prevent theft …".

                                                                                                                                                            这个以根本为目标的发现过程可以为新的和改进的解决方案开辟视野。例如,带有生物识别读取器(通常用于指纹)的键盘和鼠标现在很常见且价格低廉。如果目标是“识别和身份验证”,为什么不使用键盘上的生物识别阅读器来轻松快捷呢?但是正确回答这个问题也涉及一些可用性分析工作。他们的手指上沾满了油脂吗?他们有手指吗?

                                                                                                                                                            This root-goal discovery process can open up the vision to new and improved solutions. For example, keyboards and mice with biometric readers, usually for a fingerprint, are now common and inexpensive. If the goal is "identification and authentication" why not make it easy and fast using a biometric reader on the keyboard? But properly answering that question involves some usability analysis work as well. Are their fingers covered in grease? Do they have fingers?

                                                                                                                                                            基本风格写作

                                                                                                                                                            Essential Style Writing

                                                                                                                                                            这个想法在各种用例指南中总结为“将用户界面排除在外;专注于意图“[Cockburn01]。Larry Constantine 在创建更好的用户界面 (UI) 和进行可用性工程 [Constantine94CL99] 的上下文中更充分地探讨了它的动机和符号。Constantine 称写作风格为必要,因为它避开了 UI 细节并专注于真实的用户意图。[4]

                                                                                                                                                            This idea has been summarized in various use case guidelines as "keep the user interface out; focus on intent" [Cockburn01]. Its motivation and notation has been more fully explored by Larry Constantine in the context of creating better user interfaces (UIs) and doing usability engineering [Constantine94, CL99]. Constantine calls the writing style essential when it avoids UI details and focuses on the real user intent.[4]

                                                                                                                                                            [4] 该术语来自基本系统分析 [MP84] 中的“基本模型”。

                                                                                                                                                            [4] The term comes from "essential models" in Essential Systems Analysis [MP84].

                                                                                                                                                            在一种基本的写作风格中,叙述是在用户的意图和系统的责任层面上表达的,而不是他们的具体行动。它们仍然没有技术和机制细节,尤其是与 UI 相关的细节。

                                                                                                                                                            In an essential writing style, the narrative is expressed at the level of the user's intentions and system's responsibilities rather than their concrete actions. They remain free of technology and mechanism details, especially those related to the UI.

                                                                                                                                                            指引

                                                                                                                                                            Guideline

                                                                                                                                                            以基本风格编写用例;将用户界面排除在外,并专注于参与者意图。

                                                                                                                                                            Write use cases in an essential style; keep the user interface out and focus on actor intent.



                                                                                                                                                            本章中前面的所有示例用例(例如 Process Sale)都是针对基本样式编写的。

                                                                                                                                                            All of the previous example use cases in this chapter, such as Process Sale, were written aiming towards an essential style.

                                                                                                                                                            对比示例

                                                                                                                                                            Contrasting Examples

                                                                                                                                                            基本风格

                                                                                                                                                            假设 Manage Users (管理用户) 使用案例需要识别和身份验证:

                                                                                                                                                            Assume that the Manage Users use case requires identification and authentication:

                                                                                                                                                            1. 管理员标识 self。

                                                                                                                                                            2. Administrator identifies self.

                                                                                                                                                            3. 系统验证身份。

                                                                                                                                                            4. System authenticates identity.



                                                                                                                                                            针对这些意图和责任的设计解决方案是开放的:生物识别阅读器、图形用户界面 (GUI) 等。

                                                                                                                                                            The design solution to these intentions and responsibilities is wide open: biometric readers, graphical user interfaces (GUIs), and so forth.

                                                                                                                                                            具体样式在早期需求工作中避免

                                                                                                                                                            相比之下,有一个具体的用例风格。在这种样式中,用户界面决策嵌入到用例文本中。文本甚至可能显示窗口屏幕截图、讨论窗口导航、GUI 小部件操作等。例如:

                                                                                                                                                            In contrast, there is a concrete use case style. In this style, user interface decisions are embedded in the use case text. The text may even show window screen shots, discuss window navigation, GUI widget manipulation and so forth. For example:

                                                                                                                                                            1. 管理员在对话框中输入 ID 和密码(见图 3)。

                                                                                                                                                            2. Adminstrator enters ID and password in dialog box (see Picture 3).

                                                                                                                                                            3. 系统对 Administrator 进行身份验证。

                                                                                                                                                            4. System authenticates Administrator.

                                                                                                                                                            5. 系统显示 “edit users” 窗口(见图 4)。

                                                                                                                                                            6. System displays the "edit users" window (see Picture 4).



                                                                                                                                                            这些具体的用例可能有助于在后续步骤中进行具体或详细的 GUI 设计工作,但它们不适用于早期需求分析工作。在早期需求工作中,“使用户界面不关注意图”。

                                                                                                                                                            These concrete use cases may be useful as an aid to concrete or detailed GUI design work during a later step, but they are not suitable during the early requirements analysis work. During early requirements work, "keep the user interface outfocus on intent."

                                                                                                                                                              6.12. 指南:编写简洁的用例

                                                                                                                                                              6.12. Guideline: Write Terse Use Cases

                                                                                                                                                              你喜欢阅读很多需求吗?我不这么认为。所以,写简洁的用例。删除 “noise” 字眼。即使是很小的更改也会累积起来,例如“System authenticates...”而不是 “The System authenticates...”

                                                                                                                                                              Do you like to read lots of requirements? I didn't think so. So, write terse use cases. Delete "noise" words. Even small changes add up, such as "System authenticates…" rather than "The System authenticates…"

                                                                                                                                                                6.13. 指南:编写黑盒用例

                                                                                                                                                                6.13. Guideline: Write Black-Box Use Cases

                                                                                                                                                                黑盒用例是最常见和推荐的类型;它们不描述系统的内部工作原理、其组件或设计。相反,系统被描述为具有责任,这是面向对象思维中常见的统一隐喻主题软件元素具有责任并与其他具有责任的元素协作。

                                                                                                                                                                Black-box use cases are the most common and recommended kind; they do not describe the internal workings of the system, its components, or design. Rather, the system is described as having responsibilities, which is a common unifying metaphorical theme in object-oriented thinkingsoftware elements have responsibilities and collaborate with other elements that have responsibilities.

                                                                                                                                                                通过使用黑盒用例定义系统职责,可以指定系统必须做什么(行为或功能需求),而无需决定它将如何做(设计)。事实上,“分析”与“设计”的定义有时被概括为“什么”与“如何”。这是优秀软件开发中的一个重要主题:在需求分析期间,避免做出 “如何” 的决定,并将系统的外部行为指定为黑匣子。稍后,在设计过程中,创建符合规范的解决方案。

                                                                                                                                                                By defining system responsibilities with black-box use cases, one can specify what the system must do (the behavior or functional requirements) without deciding how it will do it (the design). Indeed, the definition of "analysis" versus "design" is sometimes summarized as "what" versus "how." This is an important theme in good software development: During requirements analysis avoid making "how" decisions, and specify the external behavior for the system, as a black box. Later, during design, create a solution that meets the specification.

                                                                                                                                                                黑盒样式

                                                                                                                                                                Black-box style

                                                                                                                                                                Not

                                                                                                                                                                系统记录销售。

                                                                                                                                                                The system records the sale.

                                                                                                                                                                系统将销售写入数据库。…或者(更糟):

                                                                                                                                                                The system writes the sale to a database. …or (even worse):

                                                                                                                                                                系统为 sale...

                                                                                                                                                                The system generates a SQL INSERT statement for the sale…



                                                                                                                                                                  6.14. 指南:采用 Actor 和 Actor-Goal 视角

                                                                                                                                                                  6.14. Guideline: Take an Actor and Actor-Goal Perspective

                                                                                                                                                                  以下是用例创始人 Ivar Jacobson 的 RUP 用例定义:

                                                                                                                                                                  Here's the RUP use case definition, from the use case founder Ivar Jacobson:

                                                                                                                                                                  一组用例实例,其中每个实例都是系统执行的一系列操作,这些操作会为特定参与者生成有价值的可观察结果。

                                                                                                                                                                  A set of use-case instances, where each instance is a sequence of actions a system performs that yields an observable result of value to a particular actor.

                                                                                                                                                                  “对特定参与者有价值的可观察结果”这句话是一个微妙但重要的概念,Jacobson 认为它至关重要,因为它在需求分析过程中强调了两种态度:

                                                                                                                                                                  The phrase "an observable result of value to a particular actor" is a subtle but important concept that Jacobson considers critical, because it stresses two attitudes during requirements analysis:

                                                                                                                                                                  • 编写以系统的用户或参与者为重点的需求,询问他们的目标和典型情况。

                                                                                                                                                                  • Write requirements focusing on the users or actors of a system, asking about their goals and typical situations.

                                                                                                                                                                  • 专注于了解参与者认为有价值的结果。

                                                                                                                                                                  • Focus on understanding what the actor considers a valuable result.

                                                                                                                                                                  也许强调提供可观察的用户价值并关注用户的典型目标似乎是显而易见的,但软件行业充斥着未能提供人们真正需要的失败项目。用于捕获需求的旧特性和功能列表方法可能会导致这种负面结果,因为它不鼓励询问谁在使用该产品,以及什么提供了价值。

                                                                                                                                                                  Perhaps it seems obvious to stress providing observable user value and focusing on users' typical goals, but the software industry is littered with failed projects that did not deliver what people really needed. The old feature and function list approach to capturing requirements can contribute to that negative outcome because it did not encourage asking who is using the product, and what provides value.

                                                                                                                                                                  功能列表 第 92

                                                                                                                                                                  function lists p. 92



                                                                                                                                                                    6.15. 指南:如何查找用例

                                                                                                                                                                    6.15. Guideline: How to Find Use Cases

                                                                                                                                                                    定义用例以满足主要参与者的目标。因此,基本过程是:

                                                                                                                                                                    Use cases are defined to satisfy the goals of the primary actors. Hence, the basic procedure is:

                                                                                                                                                                    1.
                                                                                                                                                                    选择系统边界。它只是一个软件应用程序、硬件和应用程序作为一个单元,加上使用它的人,还是整个组织?



                                                                                                                                                                    2.
                                                                                                                                                                    确定主要参与者那些通过使用系统服务实现目标的人。



                                                                                                                                                                    3.
                                                                                                                                                                    确定每个主要参与者的目标。



                                                                                                                                                                    4.
                                                                                                                                                                    定义满足用户目标的使用案例;根据他们的目标命名他们。通常,用户目标级别的用例将与用户目标一对一,但至少有一个例外,我们将进行检查。



                                                                                                                                                                    当然,在迭代和进化开发中,并非所有目标或用例都会在开始时就完全或正确地确定。这是一个不断发展的发现。

                                                                                                                                                                    Of course, in iterative and evolutionary development, not all goals or use cases will be fully or correctly identified near the start. It's an evolving discovery.

                                                                                                                                                                    步骤 1:选择系统边界

                                                                                                                                                                    Step 1: Choose the System Boundary

                                                                                                                                                                    在本案例研究中,POS 系统本身就是正在设计的系统;它之外的所有内容都位于系统边界之外,包括收银员、付款授权服务等。

                                                                                                                                                                    For this case study, the POS system itself is the system under design; everything outside of it is outside the system boundary, including the cashier, payment authorization service, and so on.

                                                                                                                                                                    如果所设计系统的边界定义不明确,可以通过进一步定义外部主要参与者和辅助参与者之外的内容来澄清。一旦确定了外部参与者,边界就会变得更加清晰。例如,支付授权的全部责任是否在系统边界内?否,存在外部支付授权服务参与者。

                                                                                                                                                                    If the definition of the boundary of the system under design is not clear, it can be clarified by further definition of what is outsidethe external primary and supporting actors. Once the external actors are identified, the boundary becomes clearer. For example, is the complete responsibility for payment authorization within the system boundary? No, there is an external payment authorization service actor.

                                                                                                                                                                    步骤 2 和 3:查找主要参与者和目标

                                                                                                                                                                    Steps 2 and 3: Find Primary Actors and Goals

                                                                                                                                                                    在用户目标之前严格线性化主要参与者的识别是人为的;在需求研讨会中,人们集思广益并产生两者的混合。有时,目标会揭示参与者,反之亦然。

                                                                                                                                                                    It is artificial to strictly linearize the identification of primary actors before user goals; in a requirements workshop, people brainstorm and generate a mixture of both. Sometimes, goals reveal the actors, or vice versa.

                                                                                                                                                                    指引:首先集思广益主要参与者,因为这为进一步调查建立了框架。

                                                                                                                                                                    Guideline: Brainstorm the primary actors first, as this sets up the framework for further investigation.

                                                                                                                                                                    是否有问题可以帮助找到参与者和目标?

                                                                                                                                                                    除了明显的主要参与者和目标外,以下问题还有助于确定可能遗漏的其他因素:

                                                                                                                                                                    In addition to obvious primary actors and goals, the following questions help identify others that may be missed:

                                                                                                                                                                    谁启动和停止系统?

                                                                                                                                                                    Who starts and stops the system?

                                                                                                                                                                    谁负责系统管理?

                                                                                                                                                                    Who does system administration?

                                                                                                                                                                    谁进行用户和安全管理?

                                                                                                                                                                    Who does user and security management?

                                                                                                                                                                    “时间”是否因为系统对时间事件执行某些操作而执行某些操作?

                                                                                                                                                                    Is "time" an actor because the system does something in response to a time event?

                                                                                                                                                                    是否有监视进程在系统失败时重新启动系统?

                                                                                                                                                                    Is there a monitoring process that restarts the system if it fails?

                                                                                                                                                                    谁评估系统活动或性能?

                                                                                                                                                                    Who evaluates system activity or performance?

                                                                                                                                                                    如何处理软件更新?推送还是拉取更新?

                                                                                                                                                                    How are software updates handled? Push or pull update?

                                                                                                                                                                    谁评估日志?它们是否被远程检索?

                                                                                                                                                                    Who evaluates logs? Are they remotely retrieved?

                                                                                                                                                                    除了人类的主要参与者之外,是否有任何外部软件或机器人系统调用系统的服务?

                                                                                                                                                                    In addition to human primary actors, are there any external software or robotic systems that call upon services of the system?

                                                                                                                                                                    当出现错误或故障时,谁会收到通知?

                                                                                                                                                                    Who gets notified when there are errors or failures?



                                                                                                                                                                    如何组织参与者和目标?

                                                                                                                                                                    至少有两种方法:

                                                                                                                                                                    There are at least two approaches:



                                                                                                                                                                    1. 当您发现结果时,将它们绘制在用例图中,并将目标命名为用例。

                                                                                                                                                                    2. As you discover the results, draw them in a use case diagram, naming the goals as use cases.

                                                                                                                                                                    3. 首先编写一个参与者目标列表,对其进行审查和完善,然后绘制用例图。

                                                                                                                                                                    4. Write an actor-goal list first, review and refine it, and then draw the use case diagram.

                                                                                                                                                                    如果您创建一个 actor-goal 列表,那么就 UP 工件而言,它可能是 Vision 工件中的一个部分。

                                                                                                                                                                    If you create an actor-goal list, then in terms of UP artifacts it may be a section in the Vision artifact.

                                                                                                                                                                    例如:

                                                                                                                                                                    For example:

                                                                                                                                                                    演员

                                                                                                                                                                    Actor

                                                                                                                                                                    目标

                                                                                                                                                                    Goal

                                                                                                                                                                     

                                                                                                                                                                    演员

                                                                                                                                                                    Actor

                                                                                                                                                                    目标

                                                                                                                                                                    Goal

                                                                                                                                                                    出纳员

                                                                                                                                                                    Cashier

                                                                                                                                                                    流程销售

                                                                                                                                                                    process sales

                                                                                                                                                                    流程租赁

                                                                                                                                                                    process rentals

                                                                                                                                                                    handle 返回

                                                                                                                                                                    handle returns

                                                                                                                                                                    兑现

                                                                                                                                                                    cash in

                                                                                                                                                                    提现

                                                                                                                                                                    cash out

                                                                                                                                                                     

                                                                                                                                                                    系統管理員

                                                                                                                                                                    System Administrator

                                                                                                                                                                    添加用户

                                                                                                                                                                    add users

                                                                                                                                                                    修改用户

                                                                                                                                                                    modify users

                                                                                                                                                                    删除用户

                                                                                                                                                                    delete users

                                                                                                                                                                    管理安全性

                                                                                                                                                                    manage security

                                                                                                                                                                    管理系统表

                                                                                                                                                                    manage system tables

                                                                                                                                                                    经理

                                                                                                                                                                    Manager

                                                                                                                                                                    启动

                                                                                                                                                                    start up

                                                                                                                                                                    关闭

                                                                                                                                                                    shut down

                                                                                                                                                                     

                                                                                                                                                                    销售活动系统

                                                                                                                                                                    Sales Activity System

                                                                                                                                                                    分析销售和绩效数据

                                                                                                                                                                    analyze sales and performance data

                                                                                                                                                                     



                                                                                                                                                                    Sales Activity System 是一个远程应用程序,它将频繁地从网络中的每个 POS 节点请求销售数据。

                                                                                                                                                                    The Sales Activity System is a remote application that will frequently request sales data from each POS node in the network.

                                                                                                                                                                    为什么要询问参与者目标而不是用例?

                                                                                                                                                                    参与者有目标,并使用应用程序来帮助满足这些目标。用例建模的观点是找到这些参与者及其目标,并创建产生价值结果的解决方案。对于用例建模者来说,这是重点的轻微转变。与其问“任务是什么”,不如先问:“谁使用这个系统,他们的目标是什么?事实上,用户目标的用例名称应反映其名称,以强调此 viewpointGoal:捕获或处理销售;用例:流程销售

                                                                                                                                                                    Actors have goals and use applications to help satisfy them. The viewpoint of use case modeling is to find these actors and their goals, and create solutions that produce a result of value. This is slight shift in emphasis for the use case modeler. Rather than asking "What are the tasks?", one starts by asking: "Who uses the system and what are their goals?" In fact, the name of a use case for a user goal should reflect its name, to emphasize this viewpointGoal: capture or process a sale; use case: Process Sale.

                                                                                                                                                                    因此,以下是有关调查需求和用例的关键思路:

                                                                                                                                                                    Thus, here is a key idea regarding investigating requirements and use cases:

                                                                                                                                                                    想象一下,我们一起参加一个需求研讨会。我们可以问:

                                                                                                                                                                    Imagine we are together in a requirements workshop. We could ask either:

                                                                                                                                                                    • “你做什么?”(大致是一个面向任务的问题)或者,

                                                                                                                                                                    • "What do you do?" (roughly a task-oriented question) or,

                                                                                                                                                                    • “你的目标是什么,其结果具有可衡量的价值?”

                                                                                                                                                                    • "What are your goals whose results have measurable value?"

                                                                                                                                                                    更喜欢第二个问题。

                                                                                                                                                                    Prefer the second question.



                                                                                                                                                                    第一个问题的答案更有可能反映当前的解决方案和程序,以及与之相关的并发症。

                                                                                                                                                                    Answers to the first question are more likely to reflect current solutions and procedures, and the complications associated with them.

                                                                                                                                                                    第二个问题的答案,特别是结合调查以提升目标层次结构(“根本目标是什么?”),为新的和改进的解决方案开辟了愿景,专注于增加业务价值,并了解利益相关者希望从系统中得到什么的核心。

                                                                                                                                                                    Answers to the second question, especially combined with an investigation to move higher up the goal hierarchy ("what is the root goal?") open up the vision for new and improved solutions, focus on adding business value, and get to the heart of what the stakeholders want from the system.

                                                                                                                                                                    收银员还是客户是主要参与者?

                                                                                                                                                                    为什么收银员而不是客户是用例 Process Sale 中的主要参与者?

                                                                                                                                                                    Why is the cashier, and not the customer, a primary actor in the use case Process Sale?

                                                                                                                                                                    答案取决于所设计系统的系统边界,以及我们主要为谁设计系统,如图 6.2 所示。如果将企业或结帐服务视为一个聚合系统,则客户主要参与者,其目标是获得商品或服务然后离开。但是,仅从 POS 系统的角度来看(这是本案例研究的系统边界选择),该系统为训练有素的收银员(和商店)处理客户销售的目标提供服务。这假设了带有收银员的传统结账环境,尽管有越来越多的自助结账 POS 系统正在运行供客户直接使用。

                                                                                                                                                                    The answer depends on the system boundary of the system under design, and who we are primarily designing the system for, as illustrated in Figure 6.2. If the enterprise or checkout service is viewed as an aggregate system, the customer is a primary actor, with the goal of getting goods or services and leaving. However, from the viewpoint of just the POS system (which is the choice of system boundary for this case study), the system services the goal of a trained cashier (and the store) to process the customer's sale. This assumes a traditional checkout environment with a cashier, although there are an increasing number of self-checkout POS systems in operation for direct use by customers.

                                                                                                                                                                    图 6.2.不同系统边界的主要参与者和目标。



                                                                                                                                                                    客户参与者,但在 NextGen POS 的上下文中,不是主要参与者;相反,收银员是主要参与者,因为该系统的设计主要服务于受训收银员的“高级用户”目标(快速处理销售、查询价格等)。该系统没有客户或收银员可以同等使用的 UI 和功能。相反,它经过优化以满足收银员的需求和培训。POS 终端前的客户不知道如何有效地使用它。换句话说,它是为收银员设计的,而不是为客户设计的,因此收银员不仅仅是客户的代理。

                                                                                                                                                                    The customer is an actor, but in the context of the NextGen POS, not a primary actor; rather, the cashier is the primary actor because the system is being designed to primarily serve the trained cashier's "power user" goals (to quickly process a sale, look up prices, etc.). The system does not have a UI and functionality that could equally be used by the customer or cashier. Rather, it is optimized to meet the needs and training of a cashier. A customer in front of the POS terminal wouldn't know how to use it effectively. In other words, it was designed for the cashier, not the customer, and so the cashier is not just a proxy for the customer.

                                                                                                                                                                    另一方面,考虑一个相同的购票网站,当客户打电话时,客户可以直接使用或电话代理使用。在这种情况下,代理只是客户的代理系统并非专门为满足代理的独特目标而设计。然后,将客户而不是电话座席显示为主要参与者是正确的。

                                                                                                                                                                    On the other hand, consider a ticket-buying website that is identical for a customer to use directly or a phone agent to use, when a customer calls in. In this case, the agent is simply a proxy for the customerthe system is not designed to especially meet the unique goals of the agent. Then, showing the customer rather than the phone agent as the primary actor is correct.

                                                                                                                                                                    寻找参与者和目标的其他方法?事件分析

                                                                                                                                                                    帮助查找参与者、目标和用例的另一种方法是识别外部事件。它们是什么,来自哪里,为什么?通常,一组事件属于同一用例。例如:

                                                                                                                                                                    Another approach to aid in finding actors, goals, and use cases is to identify external events. What are they, where from, and why? Often, a group of events belong to the same use case. For example:

                                                                                                                                                                    外部活动

                                                                                                                                                                    External Event

                                                                                                                                                                    From Actor(来自角色)

                                                                                                                                                                    From Actor

                                                                                                                                                                    目标/用例

                                                                                                                                                                    Goal/Use Case

                                                                                                                                                                    Enter Sale Line Item(输入销售行项目)

                                                                                                                                                                    enter sale line item

                                                                                                                                                                    出纳员

                                                                                                                                                                    Cashier

                                                                                                                                                                    处理销售

                                                                                                                                                                    process a sale

                                                                                                                                                                    输入付款

                                                                                                                                                                    enter payment

                                                                                                                                                                    收银员或客户

                                                                                                                                                                    Cashier or Customer

                                                                                                                                                                    处理销售

                                                                                                                                                                    process a sale

                                                                                                                                                                      



                                                                                                                                                                    第 4 步:定义用例

                                                                                                                                                                    Step 4: Define Use Cases

                                                                                                                                                                    通常,为每个用户目标定义一个用例。将用例命名为类似于用户 goal,例如 Goal: process a sale;用例:处理销售

                                                                                                                                                                    In general, define one use case for each user goal. Name the use case similar to the user goalfor example, Goal: process a sale; Use Case: Process Sale.

                                                                                                                                                                    使用案例的名称以动词开头。

                                                                                                                                                                    Start the name of use cases with a verb.



                                                                                                                                                                    每个目标一个用例的常见例外是将 CRUD(创建、检索、更新、删除)单独的目标折叠为一个 CRUD 用例,惯用地称为管理 <X>。例如,“编辑用户”、“删除用户”等目标都由 Manage Users 用例满足。

                                                                                                                                                                    A common exception to one use case per goal is to collapse CRUD (create, retrieve, update, delete) separate goals into one CRUD use case, idiomatically called Manage <X>. For example, the goals "edit user," "delete user," and so forth are all satisfied by the Manage Users use case.

                                                                                                                                                                      6.16. 指南:哪些测试可以帮助找到有用的用例?

                                                                                                                                                                      6.16. Guideline: What Tests Can Help Find Useful Use Cases?

                                                                                                                                                                      以下哪一个是有效的用例?

                                                                                                                                                                      Which of these is a valid use case?

                                                                                                                                                                      • 协商供应商合同

                                                                                                                                                                      • Negotiate a Supplier Contract

                                                                                                                                                                      • 处理退货

                                                                                                                                                                      • Handle Returns

                                                                                                                                                                      • 登录

                                                                                                                                                                      • Log In

                                                                                                                                                                      • 在游戏板上移动棋子

                                                                                                                                                                      • Move Piece on Game Board

                                                                                                                                                                      可以说,所有这些都是不同级别的用例,具体取决于系统边界、参与者和目标。

                                                                                                                                                                      An argument can be made that all of these are use cases at different levels, depending on the system boundary, actors, and goals.

                                                                                                                                                                      但是,与其笼统地问“什么是有效的用例”,不如说一个更实际的问题是:“什么是表达应用程序需求分析用例的有用级别?有几条经验法则,包括:

                                                                                                                                                                      But rather than asking in general, "What is a valid use case?", a more practical question is: "What is a useful level to express use cases for application requirements analysis?" There are several rules of thumb, including:

                                                                                                                                                                      • Boss 测试

                                                                                                                                                                      • The Boss Test

                                                                                                                                                                      • EBP 测试

                                                                                                                                                                      • The EBP Test

                                                                                                                                                                      • 尺寸测试

                                                                                                                                                                      • The Size Test

                                                                                                                                                                      Boss 测试

                                                                                                                                                                      The Boss Test

                                                                                                                                                                      你的老板问:“你一整天都在做什么?您回答:“正在登录!你的老板满意吗?

                                                                                                                                                                      Your boss asks, "What have you been doing all day?" You reply: "Logging in!" Is your boss happy?

                                                                                                                                                                      否则,该用例未通过 Boss 测试,这意味着它与实现可衡量价值的结果没有密切关系。这可能是某个低目标级别的用例,但不是需求分析的理想关注级别。

                                                                                                                                                                      If not, the use case fails the Boss Test, which implies it is not strongly related to achieving results of measurable value. It may be a use case at some low goal level, but not the desirable level of focus for requirements analysis.

                                                                                                                                                                      这并不意味着总是忽略 boss-test 失败的用例。用户身份验证可能无法通过 Boss 测试,但可能很重要且困难。

                                                                                                                                                                      That doesn't mean to always ignore boss-test-failing use cases. User authentication may fail the boss test, but may be important and difficult.

                                                                                                                                                                      EBP 测试

                                                                                                                                                                      The EBP Test

                                                                                                                                                                      初级业务流程EBP) 是业务流程工程领域的一个术语,[5] 定义为:

                                                                                                                                                                      An Elementary Business Process (EBP) is a term from the business process engineering field,[5] defined as:

                                                                                                                                                                      [5] EBP 类似于可用性工程中的术语用户任务,尽管在该领域的含义不那么严格。

                                                                                                                                                                      [5] EBP is similar to the term user task in usability engineering, although the meaning is less strict in that domain.

                                                                                                                                                                      一个人一次在一个地方执行的任务,以响应业务事件,这增加了可衡量的业务价值并使数据处于一致的状态,例如,批准信用或价格订单 [原始来源丢失]。

                                                                                                                                                                      A task performed by one person in one place at one time, in response to a business event, which adds measurable business value and leaves the data in a consistent state, e.g., Approve Credit or Price Order [original source lost].

                                                                                                                                                                      专注于反映 EBP 的使用案例。

                                                                                                                                                                      Focus on use cases that reflect EBPs.



                                                                                                                                                                      EBP 测试类似于 Boss 测试,尤其是在可衡量的商业价值鉴定方面。

                                                                                                                                                                      The EBP Test is similar to the Boss Test, especially in terms of the measurable business value qualification.

                                                                                                                                                                      这个定义可能过于字面化:如果需要两个人,或者一个人必须四处走动,用例是否无法作为 EBP?可能不是,但定义的感觉是正确的。它不是像 “delete a line item” 或 “print the document” 这样的小步骤。相反,主要的成功场景可能是 5 到 10 个步骤。它不需要几天和多次会议,比如“谈判供应商合同”;这是在单个会话期间完成的任务。它的长度可能在几分钟到一个小时之间。与 UP 的定义一样,它强调添加可观察或可衡量的商业价值,并涉及到系统和数据处于稳定和一致状态的解决方案。

                                                                                                                                                                      The definition can be taken too literally: Does a use case fail as an EBP if two people are required, or if a person has to walk around? Probably not, but the feel of the definition is about right. It's not a single small step like "delete a line item" or "print the document." Rather, the main success scenario is probably five or ten steps. It doesn't take days and multiple sessions, like "negotiate a supplier contract"; it is a task done during a single session. It is probably between a few minutes and an hour in length. As with the UP's definition, it emphasizes adding observable or measurable business value, and it comes to a resolution in which the system and data are in a stable and consistent state.

                                                                                                                                                                      尺寸测试

                                                                                                                                                                      The Size Test

                                                                                                                                                                      用例很少是单个操作或步骤;相反,一个用例通常包含许多步骤,并且在 Fully Dressed 格式中通常需要 310 页的文本。用例建模中的一个常见错误是将一系列相关步骤中的单个步骤单独定义为用例,例如定义一个名为 Enter an Item ID 的使用案例。你可以从它的小尺寸看出错误的暗示用例名称会错误地暗示更大的步骤系列中的一个步骤,如果你想象它完全修饰的文本的长度,它会非常短。

                                                                                                                                                                      A use case is very seldom a single action or step; rather, a use case typically contains many steps, and in the fully dressed format will often require 310 pages of text. A common mistake in use case modeling is to define just a single step within a series of related steps as a use case by itself, such as defining a use case called Enter an Item ID. You can see a hint of the error by its small sizethe use case name will wrongly suggest just one step within a larger series of steps, and if you imagine the length of its fully dressed text, it would be extremely short.

                                                                                                                                                                      示例:应用测试

                                                                                                                                                                      Example: Applying the Tests

                                                                                                                                                                      • 协商供应商合同

                                                                                                                                                                        • 比 EBP 更广泛、更长。可以作为业务用例建模,而不是系统用例。

                                                                                                                                                                      • Negotiate a Supplier Contract

                                                                                                                                                                        • Much broader and longer than an EBP. Could be modeled as a business use case, rather than a system use case.

                                                                                                                                                                      • 处理退货

                                                                                                                                                                        • 老板没问题。看起来像一个 EBP。尺寸很好。

                                                                                                                                                                      • Handle Returns

                                                                                                                                                                        • OK with the boss. Seems like an EBP. Size is good.

                                                                                                                                                                      • 登录

                                                                                                                                                                        • 如果这就是你一整天所做的一切,老板不高兴!

                                                                                                                                                                      • Log In

                                                                                                                                                                        • Boss not happy if this is all you do all day!

                                                                                                                                                                      • 在游戏板上移动棋子

                                                                                                                                                                        • 单步验证未通过大小测试。

                                                                                                                                                                      • Move Piece on Game Board

                                                                                                                                                                        • Single stepfails the size test.

                                                                                                                                                                      合理违反测试

                                                                                                                                                                      Reasonable Violations of the Tests

                                                                                                                                                                      尽管为应用程序识别和分析的大多数使用案例都应该满足测试,但例外情况很常见。

                                                                                                                                                                      Although the majority of use cases identified and analyzed for an application should satisfy the tests, exceptions are common.

                                                                                                                                                                      有时,在常规 EBP 级使用案例中编写单独的子函数级使用案例来表示子任务或步骤是有用的。例如,“pay by credit”等子任务或扩展可能会在多个基本使用案例中重复。如果是这样,最好将其分离到自己的用例中,即使它并不真正满足 EBP 和大小测试,并将其链接到多个基本用例,以避免文本重复。

                                                                                                                                                                      It is sometimes useful to write separate subfunction-level use cases representing subtasks or steps within a regular EBP-level use case. For example, a subtask or extension such as "paying by credit" may be repeated in several base use cases. If so, it is desirable to separate this into its own use case, even though it does not really satisfy the EBP and size tests, and link it to several base use cases, to avoid duplication of the text.

                                                                                                                                                                      有关链接子功能用例的更多信息,请参阅用例“包含”关系,第 494

                                                                                                                                                                      see the use case "include" relationship for more on linking subfunction use cases p. 494



                                                                                                                                                                      Authenticate User 可能无法通过 Boss 测试,但足够复杂,需要仔细分析,例如“单点登录”功能。

                                                                                                                                                                      Authenticate User may not pass the Boss test, but be complex enough to warrant careful analysis, such as for a "single sign-on" feature.

                                                                                                                                                                        6.17. 应用 UML:用例图

                                                                                                                                                                        6.17. Applying UML: Use Case Diagrams

                                                                                                                                                                        UML 提供了用例图表示法来说明用例和参与者的名称,以及它们之间的关系(参见图 6.3)。[6]

                                                                                                                                                                        The UML provides use case diagram notation to illustrate the names of use cases and actors, and the relationships between them (see Figure 6.3).[6]

                                                                                                                                                                        [6] “现金收入”是指收银员带着装有现金的抽屉内页到达,登录并在抽屉内页中记录现金金额的行为。

                                                                                                                                                                        [6] "Cash In" is the act of a cashier arriving with a drawer insert with cash, logging in, and recording the cash amount in the drawer insert.

                                                                                                                                                                        图 6.3.部分用例上下文图。



                                                                                                                                                                        用例图和用例关系在用例工作中是次要的。用例是文本文档。执行用例工作意味着编写文本。

                                                                                                                                                                        Use case diagrams and use case relationships are secondary in use case work. Use cases are text documents. Doing use case work means to write text.



                                                                                                                                                                        新手(或学术)用例建模者的一个常见标志是专注于用例图和用例关系,而不是编写文本。Fowler 和 Cockburn 等世界级用例专家淡化了用例图和用例关系,而是专注于写作。需要注意的是,一个简单的用例图为系统提供了一个简洁的可视化上下文图,说明了外部参与者以及他们如何使用系统。

                                                                                                                                                                        A common sign of a novice (or academic) use case modeler is a preoccupation with use case diagrams and use case relationships, rather than writing text. World-class use case experts such as Fowler and Cockburn, among others, downplay use case diagrams and use case relationships, and instead focus on writing. With that as a caveat, a simple use case diagram provides a succinct visual context diagram for the system, illustrating the external actors and how they use the system.

                                                                                                                                                                        指引

                                                                                                                                                                        Guideline

                                                                                                                                                                        绘制一个简单的用例图,并结合参与者目标列表。

                                                                                                                                                                        Draw a simple use case diagram in conjunction with an actor-goal list.



                                                                                                                                                                        用例图是系统上下文的极好图片;它是一个很好的上下文图,即显示系统的边界、系统之外的内容以及它是如何使用的。它用作汇总系统及其参与者的行为的通信工具。NextGen 系统的部分用例上下文图示例如图 6.3 所示。

                                                                                                                                                                        A use case diagram is an excellent picture of the system context; it makes a good context diagram, that is, showing the boundary of a system, what lies outside of it, and how it gets used. It serves as a communication tool that summarizes the behavior of a system and its actors. A sample partial use case context diagram for the NextGen system is shown in Figure 6.3.

                                                                                                                                                                        指南:图表

                                                                                                                                                                        Guideline: Diagramming

                                                                                                                                                                        图 6.4 提供了图表建议。请注意带有符号 “actor” 的 actor 框。这种样式用于 UML 关键字刻板印象,包括 guillemet 符号特殊的字符括号(«actor»,而不是 <<actor>>),它们在法语排版中用于表示引号而广为人知。

                                                                                                                                                                        Figure 6.4 offers diagram advice. Notice the actor box with the symbol «actor». This style is used for UML keywords and stereotypes, and includes guillemet symbolsspecial single-character brackets («actor», not <<actor>>) most widely known by their use in French typography to indicate a quote.

                                                                                                                                                                        图 6.4.符号建议。



                                                                                                                                                                        为了澄清,有些人更喜欢用另一种符号来突出显示外部计算机系统参与者,如图 6.5 所示。

                                                                                                                                                                        To clarify, some prefer to highlight external computer system actors with an alternate notation, as illustrated in Figure 6.5.

                                                                                                                                                                        图 6.5.Alternate actor 表示法。



                                                                                                                                                                        指南:淡化图表,保持简短

                                                                                                                                                                        Guideline: Downplay Diagramming, Keep it Short and Simple

                                                                                                                                                                        重申一下,重要的用例工作是编写文本,而不是图表或专注于用例关系。如果组织花费大量时间(或者更糟糕的是,数天)处理用例图并讨论用例关系,而不是专注于编写文本,那么努力就放错了地方。

                                                                                                                                                                        To reiterate, the important use case work is to write text, not diagram or focus on use case relationships. If an organization is spending many hours (or worse, days) working on a use case diagram and discussing use case relationships, rather than focusing on writing text, effort has been misplaced.

                                                                                                                                                                          6.18. 应用 UML:活动图

                                                                                                                                                                          6.18. Applying UML: Activity Diagrams

                                                                                                                                                                          UML 包括一个用于可视化工作流和业务流程的图表:活动图。由于使用案例涉及流程和工作流分析,因此这些可能是编写使用案例文本的有用替代或辅助工具,尤其是对于描述涉及多方和并发操作的复杂工作流的业务使用案例。

                                                                                                                                                                          The UML includes a diagram useful to visualize workflows and business processes: activity diagrams. Because use cases involve process and workflow analysis, these can be a useful alternative or adjunct to writing the use case text, especially for business use cases that describe complex workflows involving many parties and concurrent actions.



                                                                                                                                                                            6.19. 动机:用例的其他好处?上下文中的要求

                                                                                                                                                                            6.19. Motivation: Other Benefits of Use Cases? Requirements in Context

                                                                                                                                                                            使用案例的动机是关注关键参与者是谁、他们的目标和常见任务。此外,从本质上讲,用例是一种简单、广泛理解的形式(故事或场景形式)。

                                                                                                                                                                            A motivation for use cases is focusing on who the key actors are, their goals, and common tasks. Plus, in essence, use cases are a simple, widely-understood form (a story or scenario form).



                                                                                                                                                                            另一个动机是用用例替换详细的、低级的函数列表(这在 1970 年代的传统需求方法中很常见)。这些列表往往如下所示:

                                                                                                                                                                            Another motivation is to replace detailed, low-level function lists (which were common in 1970s traditional requirements methods) with use cases. These lists tended to look as follows:

                                                                                                                                                                            身份证

                                                                                                                                                                            ID

                                                                                                                                                                            特征

                                                                                                                                                                            Feature

                                                                                                                                                                            特点1.9

                                                                                                                                                                            FEAT1.9

                                                                                                                                                                            系统应接受输入商品编码。

                                                                                                                                                                            The system shall accept entry of item identifiers.

                                                                                                                                                                            壮举2.4

                                                                                                                                                                            FEAT2.4

                                                                                                                                                                            系统应将贷方付款记录到应收账款系统。

                                                                                                                                                                            The system shall log credit payments to the accounts receivable system.



                                                                                                                                                                            正如《用例:上下文中的需求》[GK00] 一书的标题所暗示的那样,用例在使用系统的典型场景的上下文中组织了一组需求。这是一件好事,它提高了凝聚力和理解力,以便通过面向用户的场景(即用例)的共同线程来考虑和分组需求。在最近的一个空中交通管制系统项目中:需求最初是以老式的功能列表格式编写的,填充了大量难以理解、不相关的规范。新的领导团队主要根据用例分析和重组了大量需求。这提供了一种统一且易于理解的方法,可以将需求汇总到使用上下文中的需求故事中。

                                                                                                                                                                            As implied by the title of the book Uses Cases: Requirements in Context [GK00], use cases organize a set of requirements in the context of the typical scenarios of using a system. That's a good thingit improves cohesion and comprehension to consider and group requirements by the common thread of user-oriented scenarios (i.e., use cases). In a recent air traffic control system project: the requirements were originally written in the old-fashioned function list format, filling volumes of incomprehensible, unrelated specifications. A new leadership team analyzed and reorganized the massive requirements primarily by use cases. This provided a unifying and understandable way to pull the requirements togetherinto stories of requirements in context of use.

                                                                                                                                                                            然而,重申一下,用例并不是唯一必要的需求工件。非功能性需求、报告布局、域规则和其他难以放置的元素在 UP 补充规范中得到了更好的体现。

                                                                                                                                                                            To reiterate, however, use cases are not the only necessary requirements artifact. Non-functional requirements, report layouts, domain rules, and other hard-to-place elements are better captured in the UP Supplementary Specification.



                                                                                                                                                                            高级系统功能列表是可接受的

                                                                                                                                                                            High-Level System Feature Lists Are Acceptable



                                                                                                                                                                            尽管不需要详细的功能列表,但添加到 Vision 文档的简洁、高级功能列表(称为系统功能)可以有效地总结系统功能。与 50 页的低级功能相比,系统功能列表仅包含几十个项目。它提供了独立于用例视图的功能简明摘要。例如:

                                                                                                                                                                            Although detailed function lists are undesirable, a terse, high-level feature list, called system features, added to a Vision document can usefully summarize system functionality. In contrast to 50 pages of low-level features, a system features list includes only a few dozen items. It provides a succinct summary of functionality, independent of the use case view. For example:

                                                                                                                                                                            系统功能总结

                                                                                                                                                                            Summary of System Features

                                                                                                                                                                            • 销售捕获

                                                                                                                                                                            • sales capture

                                                                                                                                                                            • 付款授权(信用卡、借记卡、支票)

                                                                                                                                                                            • payment authorization (credit, debit, check)

                                                                                                                                                                            • 用户、安全性、代码和常量表等的系统管理

                                                                                                                                                                            • system administration for users, security, code and constants tables, and so on



                                                                                                                                                                            何时适合使用详细功能列表而不是用例?

                                                                                                                                                                            When Are Detailed Feature Lists Appropriate Rather than Use Cases?

                                                                                                                                                                            有时用例并不真正适合;一些应用程序需要功能驱动的视点。例如,应用程序服务器、数据库产品和其他中间件或后端系统需要主要从功能方面考虑和发展(“我们需要在下一个版本中提供 Web 服务支持”)。用例并非天生适合这些应用程序,也不是它们在市场力量方面需要发展的方式。

                                                                                                                                                                            Sometimes use cases do not really fit; some applications cry out for a feature-driven viewpoint. For example, application servers, database products, and other middleware or back-end systems need to be primarily considered and evolved in terms of features ("We need Web Services support in the next release"). Use cases are not a natural fit for these applications or the way they need to evolve in terms of market forces.

                                                                                                                                                                              6.20. 示例:大富翁游戏

                                                                                                                                                                              6.20. Example: Monopoly Game

                                                                                                                                                                              大富翁软件系统中唯一重要的用例是玩大富翁游戏,即使它没有通过 Boss 测试!由于游戏是作为计算机模拟运行的,只是由一个人观看,因此我们可以说这个人是观察者,而不是玩家。

                                                                                                                                                                              The only significant use case in the Monopoly software system is Play Monopoly Gameeven if it doesn't pass the Boss Test! Since the game is run as a computer simulation simply watched by one person, we might say that person is an observer, not a player.

                                                                                                                                                                              此案例研究将表明,用例并不总是最适合行为要求。试图以用例格式捕获所有游戏规则是尴尬且不自然的。游戏规则属于哪里?首先,更一般地说,它们是域规则(有时称为业务规则)。在 UP 中,域规则可以是补充规范 (SS) 的一部分。在 SS 的“域规则”部分可能会引用官方纸质规则手册,或者引用描述它们的网站。此外,用例文本中可能有一个指向这些规则的指针,如下所示。

                                                                                                                                                                              This case study will show that use cases aren't always best for behavioral requirements. Trying to capture all the game rules in the use case format is awkward and unnatural. Where do the game rules belong? First, more generally, they are domain rules (sometimes called business rules). In the UP, domain rules can be part of the Supplementary Specification (SS). In the SS "domain rules" section there would probably be a reference to either the official paper booklet of rules, or to a website describing them. In addition, there may be a pointer to these rules from the use case text, as shown below.



                                                                                                                                                                              图 6.6.Monopoly 系统的用例图(“上下文图”)。



                                                                                                                                                                              此用例的文本与 NextGen POS 问题非常不同,因为它是一个简单的模拟,并且许多可能的(模拟的)玩家操作是在域规则中捕获的,而不是在 Extensions 部分中捕获的。

                                                                                                                                                                              The text for this use case is very different than the NextGen POS problem, as it is a simple simulation, and the many possible (simulated) player actions are captured in the domain rules, rather than the Extensions section.

                                                                                                                                                                              用例 UC1:玩大富翁游戏

                                                                                                                                                                              范围:垄断应用

                                                                                                                                                                              Scope: Monopoly application

                                                                                                                                                                              级别:用户目标

                                                                                                                                                                              Level: user goal

                                                                                                                                                                              主要参与者:观察者

                                                                                                                                                                              Primary Actor: Observer

                                                                                                                                                                              利益相关者和利益

                                                                                                                                                                              Stakeholders and Interests:

                                                                                                                                                                              - Observer:想要轻松观察游戏模拟的输出。



                                                                                                                                                                              - Observer: Wants to easily observe the output of the game simulation.



                                                                                                                                                                              主要成功情境

                                                                                                                                                                              Main Success Scenario:

                                                                                                                                                                              1. Observer 请求新游戏初始化,输入玩家数量。

                                                                                                                                                                              2. Observer requests new game initialization, enters number of players.

                                                                                                                                                                              3. Observer 开始播放。

                                                                                                                                                                              4. Observer starts play.

                                                                                                                                                                              5. 系统显示下一个玩家移动的游戏跟踪(有关跟踪详细信息,请参阅域规则和术语表中的“游戏跟踪”)。

                                                                                                                                                                              6. System displays game trace for next player move (see domain rules, and "game trace" in glossary for trace details).

                                                                                                                                                                              重复步骤 3,直到入选者或 Observer 取消。

                                                                                                                                                                              Repeat step 3 until a winner or Observer cancels.

                                                                                                                                                                              扩展:

                                                                                                                                                                              Extensions:

                                                                                                                                                                              *一个。在任何时候,系统都会失败:

                                                                                                                                                                              (为了支持恢复,每次完成移动后都会记录系统日志)

                                                                                                                                                                              1. Observer 重新启动系统。

                                                                                                                                                                              2. 系统检测到先前的故障,重建状态并提示继续。

                                                                                                                                                                              3. 观察者选择继续(从上次完成的玩家回合开始)。

                                                                                                                                                                              *a. At any time, System fails:

                                                                                                                                                                              (To support recovery, System logs after each completed move)

                                                                                                                                                                              1. Observer restarts System.

                                                                                                                                                                              2. System detects prior failure, reconstructs state, and prompts to continue.

                                                                                                                                                                              3. Observer chooses to continue (from last completed player turn).

                                                                                                                                                                              特殊要求:

                                                                                                                                                                              Special Requirements:

                                                                                                                                                                              - 提供图形和文本跟踪模式。

                                                                                                                                                                              - Provide both graphical and text trace modes.



                                                                                                                                                                                6.21. 流程:如何在迭代方法中处理用例?

                                                                                                                                                                                6.21. Process: How to Work With Use Cases in Iterative Methods?

                                                                                                                                                                                用例是 UP 和许多其他迭代方法的核心。UP 鼓励用例驱动的开发。这意味着:

                                                                                                                                                                                Use cases are central to the UP and many other iterative methods. The UP encourages use-case driven development. This implies:

                                                                                                                                                                                • 功能需求主要记录在用例中(用例模型);其他需求技术(例如函数列表)是次要的(如果有的话)。

                                                                                                                                                                                • Functional requirements are primarily recorded in use cases (the Use-Case Model); other requirements techniques (such as functions lists) are secondary, if used at all.

                                                                                                                                                                                • 用例是迭代规划的重要组成部分。迭代的工作部分是通过选择一些用例场景或整个用例来定义的。用例是估算的关键输入。

                                                                                                                                                                                • Use cases are an important part of iterative planning. The work of an iteration isin partdefined by choosing some use case scenarios, or entire use cases. And use cases are a key input to estimation.

                                                                                                                                                                                • 用例实现推动了设计。也就是说,团队设计协作对象和子系统,以执行或实现用例。

                                                                                                                                                                                • Use-case realizations drive the design. That is, the team designs collaborating objects and subsystems in order to perform or realize the use cases.

                                                                                                                                                                                • 用例通常会影响用户手册的组织。

                                                                                                                                                                                • Use cases often influence the organization of user manuals.

                                                                                                                                                                                • 功能或系统测试对应于用例的场景。

                                                                                                                                                                                • Functional or system testing corresponds to the scenarios of use cases.

                                                                                                                                                                                • 可以为重要用例的最常见场景创建 UI“向导”或快捷方式,以简化常见任务。

                                                                                                                                                                                • UI "wizards" or shortcuts may be created for the most common scenarios of important use cases to ease common tasks.

                                                                                                                                                                                如何在迭代中改进用例和其他规范?

                                                                                                                                                                                How to Evolve Use Cases and Other Specifications Across the Iterations?

                                                                                                                                                                                本节重申了进化迭代开发中的一个关键思想:跨迭代规范的时间和工作量级别。表 6.1 提供了一个示例(不是配方),它传达了如何开发需求的 UP 策略。

                                                                                                                                                                                This section reiterates a key idea in evolutionary iterative development: The timing and level of effort of specifications across the iterations. Table 6.1 presents a sample (not a recipe) that communicates the UP strategy of how requirements are developed.

                                                                                                                                                                                表 6.1.早期迭代中的需求工作示例;这不是一个食谱。

                                                                                                                                                                                学科

                                                                                                                                                                                Discipline

                                                                                                                                                                                人工制品

                                                                                                                                                                                Artifact

                                                                                                                                                                                注释和需求工作量级别

                                                                                                                                                                                Comments and Level of Requirements Effort

                                                                                                                                                                                因塞普

                                                                                                                                                                                Incep

                                                                                                                                                                                1 周

                                                                                                                                                                                1 week

                                                                                                                                                                                实验 1

                                                                                                                                                                                Elab 1

                                                                                                                                                                                4 周

                                                                                                                                                                                4 weeks

                                                                                                                                                                                Elab 2

                                                                                                                                                                                Elab 2

                                                                                                                                                                                4 周

                                                                                                                                                                                4 weeks

                                                                                                                                                                                实验 3

                                                                                                                                                                                Elab 3

                                                                                                                                                                                3 周

                                                                                                                                                                                3 weeks

                                                                                                                                                                                埃拉布 4

                                                                                                                                                                                Elab 4

                                                                                                                                                                                3 周

                                                                                                                                                                                3 weeks

                                                                                                                                                                                要求

                                                                                                                                                                                Requirements

                                                                                                                                                                                用例模型

                                                                                                                                                                                Use-Case Model

                                                                                                                                                                                为期 2 天的需求研讨会。大多数用例按名称标识,并在一小段中进行了总结。

                                                                                                                                                                                2-day requirements workshop. Most use cases identified by name, and summarized in a short paragraph.

                                                                                                                                                                                从高级列表中选择 10% 进行详细分析和编写。这 10% 将是架构上最重要、风险最高、业务价值最高的。

                                                                                                                                                                                Pick 10% from the high-level list to analyze and write in detail. This 10% will be the most architecturally important, risky, and high-business value.

                                                                                                                                                                                在此迭代即将结束时,举办为期 2 天的需求研讨会。从实施工作中获得洞察和反馈,然后详细完成 30% 的使用案例。

                                                                                                                                                                                Near the end of this iteration, host a 2-day requirements workshop. Obtain insight and feedback from the implementation work, then complete 30% of the use cases in detail.

                                                                                                                                                                                在此迭代即将结束时,举办为期 2 天的需求研讨会。从实施工作中获得洞察和反馈,然后详细完成 50% 的使用案例。

                                                                                                                                                                                Near the end of this iteration, host a 2-day requirements workshop. Obtain insight and feedback from the implementation work, then complete 50% of the use cases in detail.

                                                                                                                                                                                重复,详细完成 70% 的所有用例。

                                                                                                                                                                                Repeat, complete 70% of all use cases in detail.

                                                                                                                                                                                重复此操作,目标是阐明并详细编写 8090% 的用例。

                                                                                                                                                                                Repeat with the goal of 8090% of the use cases clarified and written in detail.

                                                                                                                                                                                其中只有一小部分是精心构建的;其余的在施工中完成。

                                                                                                                                                                                Only a small portion of these have been built in elaboration; the remainder are done in construction.

                                                                                                                                                                                设计

                                                                                                                                                                                Design

                                                                                                                                                                                设计模型

                                                                                                                                                                                Design Model

                                                                                                                                                                                没有

                                                                                                                                                                                none

                                                                                                                                                                                针对一小部分具有体系结构重要性的高风险要求进行设计。

                                                                                                                                                                                Design for a small set of high-risk architecturally significant requirements.

                                                                                                                                                                                重复

                                                                                                                                                                                repeat

                                                                                                                                                                                重复

                                                                                                                                                                                repeat

                                                                                                                                                                                重复。现在应该稳定高风险和具有建筑意义的方面。

                                                                                                                                                                                Repeat. The high risk and architecturally significant aspects should now be stabilized.

                                                                                                                                                                                实现

                                                                                                                                                                                Implementation

                                                                                                                                                                                实现模型(代码等)

                                                                                                                                                                                Implementation Model (code, etc.)

                                                                                                                                                                                没有

                                                                                                                                                                                none

                                                                                                                                                                                实施这些。

                                                                                                                                                                                Implement these.

                                                                                                                                                                                重复。最终系统的 5% 已经构建完成。

                                                                                                                                                                                Repeat. 5% of the final system is built.

                                                                                                                                                                                重复。最终系统的 10% 已经构建完成。

                                                                                                                                                                                Repeat. 10% of the final system is built.

                                                                                                                                                                                重复。最终系统的 15% 已经构建完成。

                                                                                                                                                                                Repeat. 15% of the final system is built.

                                                                                                                                                                                项目管理

                                                                                                                                                                                Project Management

                                                                                                                                                                                SW 发展计划

                                                                                                                                                                                SW Development Plan

                                                                                                                                                                                对总工作量的非常模糊的估计。

                                                                                                                                                                                Very vague estimate of total effort.

                                                                                                                                                                                估计开始形成。

                                                                                                                                                                                Estimate starts to take shape.

                                                                                                                                                                                好一点......

                                                                                                                                                                                a little better…

                                                                                                                                                                                好一点......

                                                                                                                                                                                a little better…

                                                                                                                                                                                现在可以合理地承诺总体项目持续时间、主要里程碑、工作量和成本估算。

                                                                                                                                                                                Overall project duration, major milestones, effort, and cost estimates can now be rationally committed to.



                                                                                                                                                                                请注意,当可能只有 10% 的需求被详细化时,技术团队开始构建系统的生产核心,事实上,该团队故意推迟继续进行深入的需求工作,直到第一次细化迭代接近尾声。

                                                                                                                                                                                Note that a technical team starts building the production core of the system when only perhaps 10% of the requirements are detailed, and in fact, the team deliberately delays in continuing with deep requirements work until near the end of the first elaboration iteration.

                                                                                                                                                                                这是迭代开发和瀑布式流程之间的关键区别:系统核心的生产质量开发很快就开始了,早在知道所有需求之前。

                                                                                                                                                                                This is a key difference between iterative development and a waterfall process: Production-quality development of the core of a system starts quickly, long before all the requirements are known.

                                                                                                                                                                                请注意,在第一次阐述迭代接近尾声时,还有第二个需求研讨会,在此期间,可能有 30% 的用例被详细编写。这种交错的需求分析受益于构建了一些核心软件的反馈。反馈包括用户评估、测试和改进的“了解我们不知道的内容”。构建软件的行为会迅速浮现出需要澄清的假设和问题。

                                                                                                                                                                                Observe that near the end of the first iteration of elaboration, there is a second requirements workshop, during which perhaps 30% of the use cases are written in detail. This staggered requirements analysis benefits from the feedback of having built a little of the core software. The feedback includes user evaluation, testing, and improved "knowing what we don't know." The act of building software rapidly surfaces assumptions and questions that need clarification.

                                                                                                                                                                                在 UP 中,鼓励在需求研讨会上编写用例。图 6.7 提供了有关执行这项工作的时间和空间的建议。

                                                                                                                                                                                In the UP, use case writing is encouraged in a requirements workshop. Figure 6.7 offers suggestions on the time and space for doing this work.

                                                                                                                                                                                图 6.7.编写用例的过程和设置上下文。



                                                                                                                                                                                何时应创建各种 UP 工件(包括用例)?

                                                                                                                                                                                When Should Various UP Artifact (Including Use Cases) be Created?

                                                                                                                                                                                表 6.2 说明了一些 UP 工件,以及它们的启动和优化计划的示例。用例模型从一开始就开始了,可能只有 10% 的架构重要用例详细编写了。大多数是在细化阶段的迭代中逐步编写的,因此在细化结束时,会编写大量详细的用例和其他需求(在补充规范中),为估算提供现实的基础,直到项目结束。

                                                                                                                                                                                Table 6.2 illustrates some UP artifacts, and an example of their start and refinement schedule. The Use-Case Model is started in inception, with perhaps only 10% of the architecturally significant use cases written in any detail. The majority are incrementally written over the iterations of the elaboration phase, so that by the end of elaboration, a large body of detailed use cases and other requirements (in the Supplementary Specification) are written, providing a realistic basis for estimation through to the end of the project.

                                                                                                                                                                                表 6.2.UP 伪影和计时示例。s - 开始;R - 优化

                                                                                                                                                                                学科

                                                                                                                                                                                Discipline

                                                                                                                                                                                人工制品

                                                                                                                                                                                Artifact

                                                                                                                                                                                因塞普。

                                                                                                                                                                                Incep.

                                                                                                                                                                                埃拉布。

                                                                                                                                                                                Elab.

                                                                                                                                                                                常量。

                                                                                                                                                                                Const.

                                                                                                                                                                                反式。

                                                                                                                                                                                Trans.

                                                                                                                                                                                迭 代

                                                                                                                                                                                Iteration

                                                                                                                                                                                I1

                                                                                                                                                                                E1..中文

                                                                                                                                                                                E1..En

                                                                                                                                                                                C1..快递 之 家

                                                                                                                                                                                C1..Cn

                                                                                                                                                                                T1..T2 航站楼

                                                                                                                                                                                T1..T2

                                                                                                                                                                                业务建模

                                                                                                                                                                                Business Modeling

                                                                                                                                                                                域模型

                                                                                                                                                                                Domain Model

                                                                                                                                                                                 

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                  

                                                                                                                                                                                要求

                                                                                                                                                                                Requirements

                                                                                                                                                                                用例模型

                                                                                                                                                                                Use-Case Model

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                r

                                                                                                                                                                                r

                                                                                                                                                                                  

                                                                                                                                                                                视觉

                                                                                                                                                                                Vision

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                r

                                                                                                                                                                                r

                                                                                                                                                                                  

                                                                                                                                                                                补充规格

                                                                                                                                                                                Supplementary Specification

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                r

                                                                                                                                                                                r

                                                                                                                                                                                  

                                                                                                                                                                                词汇表

                                                                                                                                                                                Glossary

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                r

                                                                                                                                                                                r

                                                                                                                                                                                  

                                                                                                                                                                                设计

                                                                                                                                                                                Design

                                                                                                                                                                                设计模型

                                                                                                                                                                                Design Model

                                                                                                                                                                                 

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                r

                                                                                                                                                                                r

                                                                                                                                                                                 
                                                                                                                                                                                 

                                                                                                                                                                                软件架构文档

                                                                                                                                                                                SW Architecture Document

                                                                                                                                                                                 

                                                                                                                                                                                s

                                                                                                                                                                                s

                                                                                                                                                                                  



                                                                                                                                                                                如何在 Inception 中编写用例?

                                                                                                                                                                                How to Write Use Cases in Inception?

                                                                                                                                                                                以下讨论扩展了 Table 6.1 中的信息。

                                                                                                                                                                                The following discussion expands on the information in Table 6.1.

                                                                                                                                                                                在初始阶段,并非所有用例都以完整的格式编写。相反,假设在 NextGen 早期调查期间有一个为期两天的需求研讨会。一天的早些时候用于确定目标和利益相关者,并推测项目范围内和外的内容。使用计算机投影仪编写和显示参与者-目标-用例表。将启动一个用例上下文图。几个小时后,可能会有 20 个使用案例按名称标识,包括 Process Sale、Handle Returns 等。大多数有趣、复杂或有风险的使用案例都是以简短的格式编写的,每个用例的平均编写时间约为 2 分钟。该团队开始形成系统功能的高级图景。

                                                                                                                                                                                Not all use cases are written in their fully dressed format during the inception phase. Rather, suppose there is a two-day requirements workshop during the early NextGen investigation. The earlier part of the day is spent identifying goals and stakeholders, and speculating what is in and out of scope of the project. An actor-goal-use case table is written and displayed with the computer projector. A use case context diagram is started. After a few hours, perhaps 20 use cases are identified by name, including Process Sale, Handle Returns, and so on. Most of the interesting, complex, or risky use cases are written in brief format, each averaging around two minutes to write. The team starts to form a high-level picture of the system's functionality.

                                                                                                                                                                                在此之后,10% 到 20% 的代表核心复杂功能、需要构建核心架构或在某些维度上特别危险的用例以完全修饰的格式重写;该团队通过对一小部分有影响力的用例进行深入调查,以更好地理解该项目的规模、复杂性和隐藏的恶魔。也许这意味着两个用例:处理销售和处理退货

                                                                                                                                                                                After this, 10% to 20% of the use cases that represent core complex functions, require building the core architecture, or that are especially risky in some dimension are rewritten in a fully dressed format; the team investigates a little deeper to better comprehend the magnitude, complexities, and hidden demons of the project through deep investigation of a small sample of influential use cases. Perhaps this means two use cases: Process Sale and Handle Returns.

                                                                                                                                                                                如何在阐述中编写用例?

                                                                                                                                                                                How to Write Use Cases in Elaboration?

                                                                                                                                                                                以下讨论扩展了 Table 6.1 中的信息。

                                                                                                                                                                                The following discussion expands on the information in Table 6.1.

                                                                                                                                                                                这是多个时间盒迭代(例如,四次迭代)的阶段,在这个阶段中,系统的风险、高价值或架构上重要的部分被逐步构建,并识别和澄清了“大多数”需求。来自编程具体步骤的反馈会影响并告知团队对需求的理解,这些需求是迭代和自适应改进的。也许每个 iterationfour 研讨会中都有一个为期两天的需求研讨会。但是,并非每个研讨会都会调查所有用例。他们被优先考虑;早期研讨会侧重于最重要用例的子集。

                                                                                                                                                                                This is a phase of multiple timeboxed iterations (for example, four iterations) in which risky, high-value, or architecturally significant parts of the system are incrementally built, and the "majority" of requirements identified and clarified. The feedback from the concrete steps of programming influences and informs the team's understanding of the requirements, which are iteratively and adaptively refined. Perhaps there is a two-day requirements workshop in each iterationfour workshops. However, not all use cases are investigated in each workshop. They are prioritized; early workshops focus on a subset of the most important use cases.

                                                                                                                                                                                随后的每个简短研讨会都是适应和完善核心需求愿景的时间,这些愿景在早期迭代中不稳定,在后期迭代中会稳定下来。因此,需求发现和构建软件的各个部分之间存在迭代的相互作用。

                                                                                                                                                                                Each subsequent short workshop is a time to adapt and refine the vision of the core requirements, which will be unstable in early iterations, and stabilizing in later ones. Thus, there is an iterative interplay between requirements discovery, and building parts of the software.

                                                                                                                                                                                在每次需求研讨会期间,都会细化用户目标和用例列表。更多的用例是以其完整的格式编写和重写的。在阐述结束时,“8090%” 的用例被详细编写。对于具有 20 个用户目标级别用例的 POS 系统,应以完整的格式调查、编写和重写 15 个或更多最复杂和风险的用例。

                                                                                                                                                                                During each requirements workshop, the user goals and use case list are refined. More of the use cases are written, and rewritten, in their fully dressed format. By the end of elaboration, "8090%" of the use cases are written in detail. For the POS system with 20 user-goal level use cases, 15 or more of the most complex and risky should be investigated, written, and rewritten in a fully dressed format.

                                                                                                                                                                                请注意,细化涉及对系统的各个部分进行编程。在此步骤结束时,NextGen 团队不仅应该对用例有更好的定义,还应该有一些高质量的可执行软件。

                                                                                                                                                                                Note that elaboration involves programming parts of the system. At the end of this step, the NextGen team should not only have a better definition of the use cases, but some quality executable software.

                                                                                                                                                                                如何编写建筑用例?

                                                                                                                                                                                How to Write Use Cases in Construction?

                                                                                                                                                                                构建阶段由有时间限制的迭代(例如,20 次迭代,每次两周)组成,一旦风险和核心不稳定问题在细化中得到解决,这些迭代就专注于完成系统。可能仍然有一些小的用例编写,也许还有需求研讨会,但比细化要少得多。

                                                                                                                                                                                The construction phase is composed of timeboxed iterations (for example, 20 iterations of two weeks each) that focus on completing the system, once the risky and core unstable issues have settled down in elaboration. There may still be some minor use case writing and perhaps requirements workshops, but much less so than in elaboration.

                                                                                                                                                                                案例研究:NextGen Inception 阶段的使用案例

                                                                                                                                                                                Case Study: Use Cases in the NextGen Inception Phase

                                                                                                                                                                                如前几节所述,并非所有用例在开始时都以完整的形式编写。案例研究此阶段的用例模型可以详细说明如下:

                                                                                                                                                                                As described in the previous sections, not all use cases are written in their fully dressed form during inception. The Use-Case Model at this phase of the case study could be detailed as follows:

                                                                                                                                                                                全副武装

                                                                                                                                                                                Fully Dressed

                                                                                                                                                                                休闲

                                                                                                                                                                                Casual

                                                                                                                                                                                Brief

                                                                                                                                                                                流程销售

                                                                                                                                                                                Process Sale

                                                                                                                                                                                处理退货

                                                                                                                                                                                Handle Returns

                                                                                                                                                                                流程租赁

                                                                                                                                                                                Process Rental

                                                                                                                                                                                分析销售活动

                                                                                                                                                                                Analyze Sales Activity

                                                                                                                                                                                管理安全性

                                                                                                                                                                                Manage Security

                                                                                                                                                                                提现

                                                                                                                                                                                Cash In

                                                                                                                                                                                提现

                                                                                                                                                                                Cash Out

                                                                                                                                                                                管理用户

                                                                                                                                                                                Manage Users

                                                                                                                                                                                启动

                                                                                                                                                                                Start Up

                                                                                                                                                                                关闭

                                                                                                                                                                                Shut Down

                                                                                                                                                                                管理系统表

                                                                                                                                                                                Manage System Tables



                                                                                                                                                                                  6.22. 历史

                                                                                                                                                                                  6.22. History

                                                                                                                                                                                  1986 年,UML 和 UP 的主要贡献者 Ivar Jacobson [Jacobson92] 提出了使用案例来描述功能需求的想法。Jacobson 的使用案例想法具有开创性并受到广泛赞赏。尽管许多人对这个主题做出了贡献,但可以说,在定义什么是用例以及如何编写用例方面,最有影响力和连贯的下一步来自 Alistair Cockburn(他接受过 Jacobson 的培训),基于他的早期工作和源自 1992 年以后的著作 [例如,Cockburn01]。

                                                                                                                                                                                  The idea of use cases to describe functional requirements was introduced in 1986 by Ivar Jacobson [Jacobson92], a main contributor to the UML and UP. Jacobson's use case idea was seminal and widely appreciated. Although many have made contributions to the subject, arguably the most influential and coherent next step in defining what use cases are and how to write them came from Alistair Cockburn (who was trained by Jacobson), based on his earlier work and writings stemming from 1992 onwards [e.g., Cockburn01].

                                                                                                                                                                                    6.23. 推荐资源

                                                                                                                                                                                    6.23. Recommended Resources

                                                                                                                                                                                    最流行的用例指南被翻译成多种语言,是 Writing Effective Use Cases [Cockburn01]。[7]这是有充分理由成为阅读最广泛和遵循的使用案例书,因此被推荐作为主要参考。因此,本介绍性章节基于其内容并与之一致。

                                                                                                                                                                                    The most popular use-case guide, translated into several languages, is Writing Effective Use Cases [Cockburn01].[7] This has emerged with good reason as the most widely read and followed use-case book and is therefore recommended as a primary reference. This introductory chapter is consequently based on and consistent with its content.

                                                                                                                                                                                    [7] 请注意,Cockburn 与 slow burn 押韵。

                                                                                                                                                                                    [7] Note that Cockburn rhymes with slow burn.

                                                                                                                                                                                    Adolph 和 Bramble 的 Patterns for Effective Use Cases 在某种程度上接续了 Writing 的结尾,涵盖了许多有用的提示模式格式,这些技巧与创建优秀用例的过程(团队组织、方法、编辑)以及如何更好地组织和编写它们(判断和改进其内容和组织的模式)相关。

                                                                                                                                                                                    Patterns for Effective Use Cases by Adolph and Bramble in some ways picks up where Writing leaves off, covering many useful tipsin pattern formatrelated to the process of creating excellent use cases (team organization, methodology, editing), and how to better structure and write them (patterns for judging and improving their content and organization).

                                                                                                                                                                                    用例通常最好在需求研讨会期间与合作伙伴一起编写。Ellen Gottesdiener 的 Requirements by Collaboration: Workshops for Defining Needs 是一本关于举办研讨会艺术的优秀指南。

                                                                                                                                                                                    Use cases are usually best written with a partner during a requirements workshop. An excellent guide to the art of running a workshop is Requirements by Collaboration: Workshops for Defining Needs by Ellen Gottesdiener.

                                                                                                                                                                                    Bittner 和 Spence 的《用例建模》是两位经验丰富的建模师编写的另一项优质资源,他们也了解迭代和进化开发以及 RUP,并在该上下文中提供用例分析。

                                                                                                                                                                                    Use Case Modeling by Bittner and Spence is another quality resource by two experienced modelers who also understand iterative and evolutionary development and the RUP, and present use case analysis in that context.

                                                                                                                                                                                    “Structuring Use Cases with Goals” [Cockburn97] 是关于用例引用最广泛的论文,可在 alistair.cockburn.us 在线获取。

                                                                                                                                                                                    "Structuring Use Cases with Goals" [Cockburn97] is the most widely cited paper on use cases, available online at alistair.cockburn.us.

                                                                                                                                                                                    用例:Kulak 和 Guiney 的 Requirements in Context 也很值得。它强调了一个重要的观点,正如标题所指出的那样,用例不仅仅是另一个需求工件,而是驱动需求工作的核心工具。

                                                                                                                                                                                    Use Cases: Requirements in Context by Kulak and Guiney is also worthwhile. It emphasizes the important viewpointas the title statesthat use cases are not just another requirements artifact, but are the central vehicle that drives requirements work.

                                                                                                                                                                                      第 7 章.其他要求

                                                                                                                                                                                      Chapter 7. Other Requirements

                                                                                                                                                                                      Fast, Cheap, Good: 任选两选一。

                                                                                                                                                                                      匿名

                                                                                                                                                                                      Fast, Cheap, Good: Choose any two.

                                                                                                                                                                                      anonymous

                                                                                                                                                                                      目标

                                                                                                                                                                                      Objectives

                                                                                                                                                                                      • 显示补充规范、词汇表、愿景和商业规则。

                                                                                                                                                                                      • Show Supplementary Specification, Glossary, Vision & Business Rules.

                                                                                                                                                                                      • 将系统功能与用例进行比较和对比。

                                                                                                                                                                                      • Compare and contrast system features with use cases.

                                                                                                                                                                                      • 定义质量属性。

                                                                                                                                                                                      • Define quality attributes.



                                                                                                                                                                                        介绍

                                                                                                                                                                                        Introduction

                                                                                                                                                                                        除了用例之外,还有一些其他重要的 UP 需求工件;本章将介绍它们。如果您想跳过这一章,它涉及的是需求而不是 OOA/D,没问题。跳到第 131 页的经典 OOA 主题,首先阅读了从第 124 页开始的迭代 1 需求摘要。

                                                                                                                                                                                        There are a few other important UP requirement artifacts in addition to use cases; this chapter introduces them. If you want to skip this chapterwhich deals with the secondary topic of requirements rather than OOA/Dno problem. Jump to the classic OOA subject of domain modeling on p. 131, after first reading the summary of iteration-1 requirements starting on p. 124.

                                                                                                                                                                                        那么,如果本章不是学习 OOA/D 的核心,为什么还要包括这一章呢?因为它为案例研究提供了凝聚力并提供了更完整的需求示例。

                                                                                                                                                                                        So why include this chapter if it isn't central to learning OOA/D? Because it gives cohesion to the case studies and offers a more complete requirements example.

                                                                                                                                                                                          其他需求工件

                                                                                                                                                                                          Other Requirement Artifacts

                                                                                                                                                                                          用例并不是故事的全部。

                                                                                                                                                                                          Use cases aren't the whole story.

                                                                                                                                                                                          补充规范捕获并确定了其他类型的要求,例如报告、文档、打包、可支持性、许可等。

                                                                                                                                                                                          The Supplementary Specification captures and identifies other kinds of requirements, such as reports, documentation, packaging, supportability, licensing, and so forth.

                                                                                                                                                                                          词汇表捕获了术语和定义;它还可以扮演数据字典的角色。

                                                                                                                                                                                          The Glossary captures terms and definitions; it can also play the role of a data dictionary.

                                                                                                                                                                                          愿景总结了项目的“愿景”执行摘要。它的作用是简洁地传达宏大的想法。

                                                                                                                                                                                          The Vision summarizes the "vision" of the projectan executive summary. It serves to tersely communicate the big ideas.

                                                                                                                                                                                          业务规则(或域规则)捕获超越一个特定应用程序的长期和跨区规则或策略,例如税法。

                                                                                                                                                                                          The Business Rules (or Domain Rules) capture long-living and spanning rules or policies, such as tax laws, that transcend one particular application.

                                                                                                                                                                                            7.1. 这些示例的完整性如何?

                                                                                                                                                                                            7.1. How Complete are these Examples?

                                                                                                                                                                                            本书的主要目标是基本的 OOA/D,而不是本章讨论的次要 POS 需求细节。因此,本章没有展示详尽的需求示例,[1] 而是提供了部分示例。

                                                                                                                                                                                            The book's prime goal is basic OOA/D, not the secondary POS requirement details discussed in this chapter. So rather than show exhaustive requirements examples,[1] the chapter presents partial examples.

                                                                                                                                                                                            [1] 范围蔓延不仅是需求中的问题,而且是关于需求的写作中的问题!

                                                                                                                                                                                            [1] Scope creep is not only a problem in requirements, but in writing about requirements!

                                                                                                                                                                                            简要展示了一些部分,以在以前的和未来的工作之间建立联系,突出值得注意的问题,提供对内容的感觉,并快速向前发展。

                                                                                                                                                                                            Some sections are briefly shown to make connections between prior and future work, highlight noteworthy issues, provide a feel for the contents, and move forward quickly.

                                                                                                                                                                                              7.2. 指南:我们应该在开始时彻底分析这些吗?

                                                                                                                                                                                              7.2. Guideline: Should We Analyze These Thoroughly During Inception?

                                                                                                                                                                                              不。UP 是一种迭代和进化的方法,这意味着生产质量的编程和测试应该很早就进行,远在大多数需求被完全分析或记录之前。来自早期编程和测试的反馈会改进需求。

                                                                                                                                                                                              No. The UP is an iterative and evolutionary method, which means that production-quality programming and testing should happen very early, long before most requirements have been fully analyzed or recorded. Feedback from early programming and tests evolve the requirements.

                                                                                                                                                                                              但是,研究表明,在开始时有一个高级的 “top ten” 粗粒度需求列表是有用的。花大量时间了解非功能性需求(比如性能或可靠性)也是有用的,因为这些需求对架构选择有重大影响。

                                                                                                                                                                                              However, research shows that is useful to have a high-level "top ten" list of coarse-grained requirements near the start. It is also useful to spend non-trivial early time understanding the non-functional requirements (such as performance or reliability), as these have a significant impact on architectural choices.

                                                                                                                                                                                              可靠的规格:矛盾的说法?

                                                                                                                                                                                              Reliable Specifications: An Oxymoron?

                                                                                                                                                                                              以下书面需求示例可能会营造一种错觉,即真正的需求被理解和明确定义,并且可以(早期)用于可靠地估计和规划项目。这种错觉对于非软件开发人员来说更为强烈;程序员从痛苦的经验中知道它有多么不可靠。如前所述,案例研究(例如,[Thomas01] 和 [Larman03])现在表明,认为早期的详细需求在软件项目中是有用的或可靠的是一种误解。事实上,恰恰相反,因为几乎 50% 的早期瀑布式指定功能从未在系统中使用过。

                                                                                                                                                                                              The following written requirement examples could promote the illusion that the real requirements are understood and well-defined, and can (early on) be used to reliably estimate and plan the project. This illusion is more strong for non-software developers; programmers know from painful experience how unreliable it is. As mentioned, case studies (for example, [Thomas01] and [Larman03]) now show it is a misunderstanding to believe that early detailed requirements are useful or reliable on software projects. In fact, quite the opposite, as almost 50% of early waterfall-specified features are never used in a system.

                                                                                                                                                                                              真正重要的是快速构建通过用户定义的验收测试并满足他们真正目标的软件,这些目标通常只有在用户评估或使用软件时才会被发现。

                                                                                                                                                                                              What really matters is quickly building software that passes the acceptance tests defined by the users, and that meets their true goalswhich are often not discovered until users are evaluating or working with the software.

                                                                                                                                                                                              编写 Vision and Supplementary Specification 是值得的,因为它可以阐明所需内容的第一个近似值、产品的动机,并作为大想法的存储库。但它们不是,也不是任何需求工件的可靠规范。只有编写代码、测试代码、获取反馈、与用户和客户持续密切合作以及适应,才能真正达到目标。

                                                                                                                                                                                              Writing a Vision and Supplementary Specification is worthwhile as an exercise in clarifying a first approximation of what is wanted, the motivation for the product, and as a repository for the big ideas. But they are notnor is any requirements artifacta reliable specification. Only writing code, testing it, getting feedback, ongoing close collaboration with users and customers, and adapting, truly hit the mark.

                                                                                                                                                                                              这并不是呼吁放弃分析和思考,只匆忙编写代码,而是建议轻视书面需求,尽早开始编程,并持续理想地每天吸引用户和测试反馈。

                                                                                                                                                                                              This is not a call to abandon analysis and thinking, and just rush to code, but a suggestion to treat written requirements lightly, start programming early, and continuallyideally, dailyengage users and tests for feedback.

                                                                                                                                                                                                7.3. 指南:这些工件应该放在项目网站上吗?

                                                                                                                                                                                                7.3. Guideline: Should These Artifacts be at the Project Website?

                                                                                                                                                                                                绝对。由于这是一本书,因此这些示例和用例具有静态的,并且可能面向纸张的感觉。然而,这些通常应该是仅在项目网站上在线录制的数字文物。它们不是普通的静态文档,而是超链接,或记录在文字处理器或电子表格以外的工具中。例如,其中许多可以存储在 Wiki Web 中。[2]

                                                                                                                                                                                                Definitely. Since this is a book, these examples and the use cases have a static and perhaps paper-oriented feel. Nevertheless, these should usually be digital artifacts recorded only online at the project website. And instead of being plain static documents, they may be hyperlinked, or recorded in tools other than a word processor or spreadsheet. For example, many of these could be stored in a Wiki Web.[2]

                                                                                                                                                                                                [2] 有关 Wiki 的介绍,请参阅 http://en.wikipedia.org/wiki/WikiWiki

                                                                                                                                                                                                [2] For an introduction to Wikis, see http://en.wikipedia.org/wiki/WikiWiki.

                                                                                                                                                                                                  7.4. NextGen 示例:(部分)补充规范

                                                                                                                                                                                                  7.4. NextGen Example: (Partial) Supplementary Specification

                                                                                                                                                                                                  补充规格

                                                                                                                                                                                                  Supplementary Specification

                                                                                                                                                                                                  修订历史记录

                                                                                                                                                                                                  Revision History

                                                                                                                                                                                                  版本

                                                                                                                                                                                                  Version

                                                                                                                                                                                                  日期

                                                                                                                                                                                                  Date

                                                                                                                                                                                                  描述

                                                                                                                                                                                                  Description

                                                                                                                                                                                                  作者

                                                                                                                                                                                                  Author

                                                                                                                                                                                                  初始草稿

                                                                                                                                                                                                  Inception draft

                                                                                                                                                                                                  1月 10, 2031

                                                                                                                                                                                                  Jan 10, 2031

                                                                                                                                                                                                  初稿。主要在阐述过程中进行提炼。

                                                                                                                                                                                                  First draft. To be refined primarily during elaboration.

                                                                                                                                                                                                  克雷格·拉曼

                                                                                                                                                                                                  Craig Larman

                                                                                                                                                                                                      



                                                                                                                                                                                                  介绍

                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                  本文档是用例中未捕获的所有 NextGen POS 要求的存储库。

                                                                                                                                                                                                  This document is the repository of all NextGen POS requirements not captured in the use cases.

                                                                                                                                                                                                  功能性

                                                                                                                                                                                                  Functionality

                                                                                                                                                                                                  (许多使用案例中通用的功能)

                                                                                                                                                                                                  (Functionality common across many use cases)

                                                                                                                                                                                                  日志记录和错误处理

                                                                                                                                                                                                  Logging and Error Handling

                                                                                                                                                                                                  将所有错误记录到持久性存储中。

                                                                                                                                                                                                  Log all errors to persistent storage.

                                                                                                                                                                                                  可插拔规则

                                                                                                                                                                                                  Pluggable Rules

                                                                                                                                                                                                  在几个用例(待定义)的不同场景点上,支持使用一组在该点或事件执行的任意规则来自定义系统的功能。

                                                                                                                                                                                                  At various scenario points of several use cases (to be defined) support the ability to customize the functionality of the system with a set of arbitrary rules that execute at that point or event.

                                                                                                                                                                                                  安全

                                                                                                                                                                                                  Security

                                                                                                                                                                                                  所有使用都需要用户身份验证。

                                                                                                                                                                                                  All usage requires user authentication.

                                                                                                                                                                                                  可用性

                                                                                                                                                                                                  Usability

                                                                                                                                                                                                  人为因素

                                                                                                                                                                                                  Human Factors

                                                                                                                                                                                                  客户将能够看到 POS 的大显示器显示。因此:

                                                                                                                                                                                                  The customer will be able to see a large-monitor display of the POS. Therefore:

                                                                                                                                                                                                  • 文本应在 1 米外易于看到。

                                                                                                                                                                                                  • Text should be easily visible from 1 meter.

                                                                                                                                                                                                  • 避免使用与常见色盲相关的颜色。

                                                                                                                                                                                                  • Avoid colors associated with common forms of color blindness.

                                                                                                                                                                                                  速度、易用性和无差错的处理在销售处理中至关重要,因为买家希望快速离开,或者他们认为购买体验(和卖家)不太积极。

                                                                                                                                                                                                  Speed, ease, and error-free processing are paramount in sales processing, as the buyer wishes to leave quickly, or they perceive the purchasing experience (and seller) as less positive.

                                                                                                                                                                                                  收银员经常看客户或商品,而不是电脑显示屏。因此,信号和警告应该通过声音传达,而不仅仅是通过图形。

                                                                                                                                                                                                  The cashier is often looking at the customer or items, not the computer display. Therefore, signals and warnings should be conveyed with sound rather than only via graphics.

                                                                                                                                                                                                  可靠性

                                                                                                                                                                                                  Reliability

                                                                                                                                                                                                  可恢复性

                                                                                                                                                                                                  Recoverability

                                                                                                                                                                                                  如果无法使用外部服务(支付授权人、会计系统等),请尝试使用本地解决方案(例如,存储和转发)来解决,以便仍然完成销售。这里需要更多的分析......

                                                                                                                                                                                                  If there is failure to use external services (payment authorizer, accounting system, ...) try to solve with a local solution (e.g., store and forward) in order to still complete a sale. Much more analysis is needed here...

                                                                                                                                                                                                  性能

                                                                                                                                                                                                  Performance

                                                                                                                                                                                                  正如人为因素中所述,买家希望非常快速地完成销售处理。一个瓶颈是外部支付授权。我们的目标:在 90% 的时间内,在 1 分钟内完成授权。

                                                                                                                                                                                                  As mentioned under human factors, buyers want to complete sales processing very quickly. One bottleneck is external payment authorization. Our goal: authorization in less than1 minute, 90% of the time.

                                                                                                                                                                                                  保障性

                                                                                                                                                                                                  Supportability

                                                                                                                                                                                                  适应性

                                                                                                                                                                                                  Adaptability

                                                                                                                                                                                                  NextGen POS 的不同客户在处理销售时具有独特的业务规则和处理需求。因此,在方案中的多个定义点(例如,当开始新销售时,当添加新的行项目时),将启用可插入业务规则。

                                                                                                                                                                                                  Different customers of the NextGen POS have unique business rule and processing needs while processing a sale. Therefore, at several defined points in the scenario (for example, when a new sale is initiated, when a new line item is added) pluggable business rule will be enabled.

                                                                                                                                                                                                  可配置性

                                                                                                                                                                                                  Configurability

                                                                                                                                                                                                  不同的客户希望其 POS 系统使用不同的网络配置,例如胖客户端与瘦客户端、双层物理层与 N 层物理层等。此外,他们希望能够修改这些配置,以反映其不断变化的业务和性能需求。因此,系统将在某种程度上进行配置以反映这些需求。在这个领域需要更多的分析,以发现灵活性的领域和程度,以及为实现它所做的努力。

                                                                                                                                                                                                  Different customers desire varying network configurations for their POS systems, such as thick versus thin clients, two-tier versus N-tier physical layers, and so forth. In addition, they desire the ability to modify these configurations, to reflect their changing business and performance needs. Therefore, the system will be somewhat configurable to reflect these needs. Much more analysis is needed in this area to discover the areas and degree of flexibility, and the effort to achieve it.

                                                                                                                                                                                                  实现约束

                                                                                                                                                                                                  Implementation Constraints

                                                                                                                                                                                                  NextGen 领导层坚持使用 Java 技术解决方案,并预测这将提高长期移植和可支持性,以及简化开发。

                                                                                                                                                                                                  NextGen leadership insists on a Java technologies solution, predicting this will improve long-term porting and supportability, in addition to ease of development.

                                                                                                                                                                                                  外购组件

                                                                                                                                                                                                  Purchased Components

                                                                                                                                                                                                  • 税计算器。必须支持不同国家/地区的可插拔计算器。

                                                                                                                                                                                                  • Tax calculator. Must support pluggable calculators for different countries.

                                                                                                                                                                                                  免费的开源组件

                                                                                                                                                                                                  Free Open Source Components

                                                                                                                                                                                                  一般来说,我们建议在此项目中最大限度地使用免费的 Java 技术开源组件。

                                                                                                                                                                                                  In general, we recommend maximizing the use of free Java technology open source components on this project.

                                                                                                                                                                                                  虽然现在明确设计和选择组件还为时过早,但我们建议以下选项作为可能的候选者:

                                                                                                                                                                                                  Although it is premature to definitively design and choose components, we suggest the following as likely candidates:

                                                                                                                                                                                                  • JLog 日志记录框架

                                                                                                                                                                                                  • JLog logging framework

                                                                                                                                                                                                  接口

                                                                                                                                                                                                  Interfaces

                                                                                                                                                                                                  值得注意的硬件和接口

                                                                                                                                                                                                  Noteworthy Hardware and Interfaces

                                                                                                                                                                                                  • 触摸屏监视器(操作系统将其视为常规监视器,而触摸手势将其视为鼠标事件)

                                                                                                                                                                                                  • Touch screen monitor (this is perceived by operating systems as a regular monitor, and the touch gestures as mouse events)

                                                                                                                                                                                                  • 条形码激光扫描仪(这些扫描仪通常连接到特殊键盘上,扫描的输入在软件中被视为击键)

                                                                                                                                                                                                  • Barcode laser scanner (these normally attach to a special keyboard, and the scanned input is perceived in software as keystrokes)

                                                                                                                                                                                                  • 收据打印机

                                                                                                                                                                                                  • Receipt printer

                                                                                                                                                                                                  • 信用卡/借记卡读卡器

                                                                                                                                                                                                  • Credit/debit card reader

                                                                                                                                                                                                  • 签名读取器(但不在版本 1 中)

                                                                                                                                                                                                  • Signature reader (but not in release 1)

                                                                                                                                                                                                  软件接口

                                                                                                                                                                                                  Software Interfaces

                                                                                                                                                                                                  对于大多数外部协作系统(税收计算器、会计、库存等),我们需要能够插入不同的系统,从而插入不同的接口。

                                                                                                                                                                                                  For most external collaborating systems (tax calculator, accounting, inventory, ... ) we need to be able to plug in varying systems and thus varying interfaces.

                                                                                                                                                                                                  特定于应用程序的域 (业务) 规则

                                                                                                                                                                                                  Application-Specific Domain (Business) Rules

                                                                                                                                                                                                  (有关一般规则,请参阅单独的 Business Rules 文档。

                                                                                                                                                                                                  (See the separate Business Rules document for general rules.)

                                                                                                                                                                                                  身份证

                                                                                                                                                                                                  ID

                                                                                                                                                                                                  统治

                                                                                                                                                                                                  Rule

                                                                                                                                                                                                  多变性

                                                                                                                                                                                                  Changeability

                                                                                                                                                                                                  Source

                                                                                                                                                                                                  规则 1

                                                                                                                                                                                                  RULE1

                                                                                                                                                                                                  购买者折扣规则。例子:

                                                                                                                                                                                                  Purchaser discount rules. Examples:

                                                                                                                                                                                                  员工 20% 折扣。

                                                                                                                                                                                                  Employee20% off.

                                                                                                                                                                                                  优惠顾客10% 折扣。

                                                                                                                                                                                                  Preferred Customer10% off.

                                                                                                                                                                                                  老年人15% 折扣。

                                                                                                                                                                                                  Senior15% off.

                                                                                                                                                                                                  高。

                                                                                                                                                                                                  High.

                                                                                                                                                                                                  每个零售商使用不同的规则。

                                                                                                                                                                                                  Each retailer uses different rules.

                                                                                                                                                                                                  零售商政策。

                                                                                                                                                                                                  Retailer policy.

                                                                                                                                                                                                  规则 2

                                                                                                                                                                                                  RULE2

                                                                                                                                                                                                  销售 (交易级别) 折扣规则。

                                                                                                                                                                                                  Sale (transaction-level) discount rules.

                                                                                                                                                                                                  适用于税前合计。例子:

                                                                                                                                                                                                  Applies to pre-tax total. Examples:

                                                                                                                                                                                                  如果总额超过 100 美元,则可享受 10% 的折扣。

                                                                                                                                                                                                  10% off if total greater than $100 USD.

                                                                                                                                                                                                  每周一 5% 折扣。

                                                                                                                                                                                                  5% off each Monday.

                                                                                                                                                                                                  今天上午 10 点至下午 3 点的所有销售可享受 10% 的折扣。

                                                                                                                                                                                                  10% off all sales from 10am to 3pm today.

                                                                                                                                                                                                  豆腐今天上午 9 点至上午 10 点可享受 50% 的折扣。

                                                                                                                                                                                                  Tofu 50% off from 9am-10am today.

                                                                                                                                                                                                  高。

                                                                                                                                                                                                  High.

                                                                                                                                                                                                  每个零售商使用不同的规则,并且它们可能每天或每小时更改一次。

                                                                                                                                                                                                  Each retailer uses different rules, and they may change daily or hourly.

                                                                                                                                                                                                  零售商政策。

                                                                                                                                                                                                  Retailer policy.

                                                                                                                                                                                                  规则 3

                                                                                                                                                                                                  RULE3

                                                                                                                                                                                                  产品 (行项目级别) 折扣规则。

                                                                                                                                                                                                  Product (line item level) discount rules.

                                                                                                                                                                                                  例子:

                                                                                                                                                                                                  Examples:

                                                                                                                                                                                                  本周拖拉机可享受 10% 的折扣。

                                                                                                                                                                                                  10% off tractors this week.

                                                                                                                                                                                                  买 2 个素食汉堡送 1 个。

                                                                                                                                                                                                  Buy 2 veggieburgers, get 1 free.

                                                                                                                                                                                                  高。

                                                                                                                                                                                                  High.

                                                                                                                                                                                                  每个零售商使用不同的规则,并且它们可能每天或每小时更改一次。

                                                                                                                                                                                                  Each retailer uses different rules, and they may change daily or hourly.

                                                                                                                                                                                                  零售商政策。

                                                                                                                                                                                                  Retailer policy.



                                                                                                                                                                                                  法律问题

                                                                                                                                                                                                  Legal Issues

                                                                                                                                                                                                  如果可以解决开源组件的许可限制以允许转售包含开源软件的商品,我们建议使用一些开源组件。

                                                                                                                                                                                                  We recommend some open source components if their licensing restrictions can be resolved to allow resale of products that include open source software.

                                                                                                                                                                                                  根据法律,所有税务规则都必须在销售期间适用。请注意,这些可能会经常更改。

                                                                                                                                                                                                  All tax rules must, by law, be applied during sales. Note that these can change frequently.

                                                                                                                                                                                                  感兴趣域中的信息

                                                                                                                                                                                                  Information in Domains of Interest

                                                                                                                                                                                                  定价

                                                                                                                                                                                                  Pricing

                                                                                                                                                                                                  除了域规则部分中描述的定价规则外,请注意,产品具有原价永久降价(可选)。商品的价格(进一步折扣之前)是永久降价价格(如果存在)。出于会计和税务原因,即使有永久的降价,组织也会保持原价。

                                                                                                                                                                                                  In addition to the pricing rules described in the domain rules section, note that products have an original price, and optionally a permanent markdown price. A product's price (before further discounts) is the permanent markdown price, if present. Organizations maintain the original price even if there is a permanent markdown price, for accounting and tax reasons.

                                                                                                                                                                                                  贷记和借记付款处理

                                                                                                                                                                                                  Credit and Debit Payment Handling

                                                                                                                                                                                                  当付款授权服务批准电子信用卡或借记卡付款时,他们负责向卖家付款,而不是买家。因此,对于每笔付款,卖方都需要在授权服务的应收账款中记录欠款。通常每晚,授权服务将向卖家账户进行电子资金转账,金额为每日总欠款减去服务收取的每笔交易费用(小额)。

                                                                                                                                                                                                  When an electronic credit or debit payment is approved by a payment authorization service, they are responsible for paying the seller, not the buyer. Consequently, for each payment, the seller needs to record monies owing in their accounts receivable, from the authorization service. Usually on a nightly basis, the authorization service will perform an electronic funds transfer to the seller's account for the daily total owing, less a (small) per transaction fee that the service charges.

                                                                                                                                                                                                  营业税

                                                                                                                                                                                                  Sales Tax

                                                                                                                                                                                                  销售税的计算可能非常复杂,并且会根据各级政府的立法定期更改。因此,建议将税收计算委托给第三方计算器软件(其中有几种可用)。税款可能应向城市、地区、州和国家机构缴纳。某些商品可能无条件免税,也可能免税,具体取决于买家或目标收件人(例如,农民或儿童)。

                                                                                                                                                                                                  Sales tax calculations can be very complex, and regularly change in response to legislation at all levels of government. Therefore, delegating tax calculations to third-party calculator software (of which there are several available) is advisable. Tax may be owing to city, region, state, and national bodies. Some items may be tax exempt without qualification, or exempt depending on the buyer or target recipient (for example, a farmer or a child).

                                                                                                                                                                                                  商品编码: UPC、EAN、SKU、条形码和条形码阅读器

                                                                                                                                                                                                  Item Identifiers: UPCs, EANs, SKUs, Bar Codes, and Bar Code Readers

                                                                                                                                                                                                  NextGen POS 需要支持各种商品标识符方案。UPC(通用商品代码)、EAN(欧洲商品编号)和 SKU(库存单位)是所售商品的三种常见编码系统。日本商品编号 (JAN) 是一种 EAN 版本。

                                                                                                                                                                                                  The NextGen POS needs to support various item identifier schemes. UPCs (Universal Product Codes), EANs (European Article Numbering) and SKUs (Stock Keeping Units) are three common identifier systems for products that are sold. Japanese Article Numbers (JANs) are a kind of EAN version.

                                                                                                                                                                                                  SKU 是零售商定义的完全任意的标识符。

                                                                                                                                                                                                  SKUs are completely arbitrary identifiers defined by the retailer.

                                                                                                                                                                                                  但是,UPC 和 EAN 具有标准和监管组成部分。有关良好的概述,请参见 www.adams1.com/pub/russadam/upccode.html。另请参阅 www.uc-council.orgwww.ean-int.org

                                                                                                                                                                                                  However, UPCs and EANs have a standards and regulatory component. See www.adams1.com/pub/russadam/upccode.html for a good overview. Also see www.uc-council.org and www.ean-int.org.



                                                                                                                                                                                                    7.5. 注释:补充规范

                                                                                                                                                                                                    7.5. Commentary: Supplementary Specification

                                                                                                                                                                                                    补充规范捕获了用例或术语表中不容易捕获的其他要求、信息和约束,包括系统范围的“URPS+”(usability、rereliability、performance、supportability 等)质量属性或要求。

                                                                                                                                                                                                    The Supplementary Specification captures other requirements, information, and constraints not easily captured in the use cases or Glossary, including system-wide "URPS+" (usability, reliability, performance, supportability, and more) quality attributes or requirements.

                                                                                                                                                                                                    请注意,在您考虑用例时,特定于用例的非功能性要求可以(并且可能应该)首先在用例中的 Special Requirements 部分简要编写。但是,在那个非正式的步骤之后,这些应该被移动到补充规范中,将所有非功能性需求放在一个地方,而不是重复。

                                                                                                                                                                                                    Note that non-functional requirements specific to a use case can (and probably should) be first briefly written within the use case, in the Special Requirements section while you are thinking through the use case. But, after that informal step, these should then be moved to the Supplementary Specification, to keep all non-functional requirements in one place, and not duplicated.

                                                                                                                                                                                                    补充规范的要素包括:

                                                                                                                                                                                                    Elements of the Supplementary Specification include:

                                                                                                                                                                                                    • FURPS+ 要求功能性、可用性、可靠性、性能和可支持性

                                                                                                                                                                                                    • FURPS+ requirementsfunctionality, usability, reliability, performance, and supportability

                                                                                                                                                                                                    • 报告

                                                                                                                                                                                                    • reports

                                                                                                                                                                                                    • 硬件和软件限制(操作和网络系统等)

                                                                                                                                                                                                    • hardware and software constraints (operating and networking systems, …)

                                                                                                                                                                                                    • 开发约束(例如,流程或开发工具)

                                                                                                                                                                                                    • development constraints (for example, process or development tools)

                                                                                                                                                                                                    • 其他设计和实现约束

                                                                                                                                                                                                    • other design and implementation constraints

                                                                                                                                                                                                    • 国际化问题(单位、语言)

                                                                                                                                                                                                    • internationalization concerns (units, languages)

                                                                                                                                                                                                    • 文档(用户、安装、管理)和帮助

                                                                                                                                                                                                    • documentation (user, installation, administration) and help

                                                                                                                                                                                                    • 许可和其他法律问题

                                                                                                                                                                                                    • licensing and other legal concerns

                                                                                                                                                                                                    • 包装

                                                                                                                                                                                                    • packaging

                                                                                                                                                                                                    • 标准(技术、安全、质量)

                                                                                                                                                                                                    • standards (technical, safety, quality)

                                                                                                                                                                                                    • 物理环境问题(例如,热量或振动)

                                                                                                                                                                                                    • physical environment concerns (for example, heat or vibration)

                                                                                                                                                                                                    • 操作问题(例如,如何处理错误,或者应该多久进行一次备份?

                                                                                                                                                                                                    • operational concerns (for example, how do errors get handled, or how often should backups be done?)

                                                                                                                                                                                                    • 特定于应用程序的域规则

                                                                                                                                                                                                    • application-specific domain rules

                                                                                                                                                                                                    • 感兴趣域中的信息(例如,信用付款处理的整个周期是什么?

                                                                                                                                                                                                    • information in domains of interest (for example, what is the entire cycle of credit payment handling?)

                                                                                                                                                                                                    质量属性

                                                                                                                                                                                                    Quality Attributes

                                                                                                                                                                                                    某些需求称为系统的质量属性 [BCK98](或“-ilities”)。这些因素包括可用性、可靠性等。请注意,这些是系统的品质,而不是属性本身的品质,属性本身不一定是高质量的。例如,如果产品不打算用于长期目的,则可能会故意将可支撑性的质量选择得较低。

                                                                                                                                                                                                    Some requirements are called quality attributes [BCK98] (or "-ilities") of a system. These include usability, reliability, and so forth. Note that these are qualities of the system, not of the attributes themselves, which are not necessarily of high quality. For example, the quality of supportability might deliberately be chosen to be low if the product is not intended to serve a long-term purpose.

                                                                                                                                                                                                    当我们戴上 “架构师的帽子” 时,系统范围的质量属性(以及记录它们的补充规范)特别有趣,因为将在第 33 章中介绍架构分析和设计主要关注在功能需求上下文中质量属性的识别和解决

                                                                                                                                                                                                    When we put on our "architect hat," the system-wide quality attributes (and thus the Supplementary Specification where one records them) are especially interesting becauseas will be introduced in Chapter 33architectural analysis and design are largely concerned with the identification and resolution of the quality attributes in the context of the functional requirements.

                                                                                                                                                                                                    例如,假设其中一个质量属性是 NextGen 系统在远程服务失败时必须具有相当的容错能力。从架构的角度来看,这将对大规模设计决策产生总体影响。

                                                                                                                                                                                                    For example, suppose one of the quality attributes is that the NextGen system must be quite fault-tolerant when remote services fail. From an architectural viewpoint, that will have an overarching influence on large-scale design decisions.

                                                                                                                                                                                                    补充规范中的功能?这不应该出现在 Use Cases 中吗?

                                                                                                                                                                                                    Functionality in the Supplementary Spec? Shouldn't that be in the Use Cases?

                                                                                                                                                                                                    某些函数或特性不适合用例格式。在 1990 年代,我在一家公司工作,该公司构建了 Java 中间件和基于代理的平台。对于下一个版本(与大多数中间件或服务器产品一样),我们没有从用例的角度考虑其功能,这没有意义。但我们确实从功能方面考虑了功能,例如“添加 EJB Entity Bean 1.0 支持”。

                                                                                                                                                                                                    Some functions or features don't fit in a use case format. In the 1990s I worked at a company that built a Java middleware and agent-based platform. For the next release (as with most middleware or server products) we didn't think of its functionality in terms of use casesdidn't make sense. But we did think of the functionality in terms of features, such as "add EJB Entity Bean 1.0 support."

                                                                                                                                                                                                    UP 当然允许这种面向特性的需求方法,在这种情况下,特性列表放在补充规范中。

                                                                                                                                                                                                    The UP certainly allows this feature-oriented approach to requirements, in which case the feature list goes in the Supplementary Specification.

                                                                                                                                                                                                    UP 鼓励但不要求功能用例;用例是根据使用产品的典型场景来思考和整合一组相关功能的好方法。他们并不总是适合。

                                                                                                                                                                                                    The UP encourages but does not require use cases for functionality; use cases are a great way to think about and pull together a related set of features in terms of typical scenarios of using a product. They don't always fit.

                                                                                                                                                                                                    特定于应用程序的域 (业务) 规则

                                                                                                                                                                                                    Application-Specific Domain (Business) Rules

                                                                                                                                                                                                    一般、广泛的域规则(如税法)属于 UP Business Rules 构件,作为中央共享存储库。但是,更狭义的应用程序特定规则(例如如何计算行项目折扣)可以记录在补充规范中。

                                                                                                                                                                                                    General, broad domain rules such as tax laws belong in the UP Business Rules artifact, as a central shared repository. However, more narrow application-specific rules, such as how to calculate a line-item discount, can be recorded in the Supplementary Specification.

                                                                                                                                                                                                    感兴趣域中的信息

                                                                                                                                                                                                    Information in Domains of Interest

                                                                                                                                                                                                    对于主题专家来说,撰写(或提供 URI)与新软件系统相关的领域(销售和会计、地下石油/水/天然气流的地球物理学等)的一些解释通常是有价值的,以便为开发团队提供背景和更深入的见解。该文件可能包含指向重要文献或专家、公式、法律或其他参考资料的指针。例如,NextGen 团队必须在一定程度上理解 UPC 和 EAN 编码方案的奥秘以及条形码符号系统。

                                                                                                                                                                                                    It is often valuable for a subject matter expert to write (or provide URIs to) some explanation of domains related to the new software system (sales and accounting, the geophysics of underground oil/water/gas flows, …), to provide context and deeper insight for the development team. That document may contain pointers to important literature or experts, formulas, laws, or other references. For example, the arcana of UPC and EAN coding schemes, and bar code symbology, must be understood to some degree by the NextGen team.

                                                                                                                                                                                                      7.6. NextGen 示例:(部分)视力

                                                                                                                                                                                                      7.6. NextGen Example: (Partial) Vision

                                                                                                                                                                                                      视觉

                                                                                                                                                                                                      Vision

                                                                                                                                                                                                      修订历史记录

                                                                                                                                                                                                      Revision History

                                                                                                                                                                                                      版本

                                                                                                                                                                                                      Version

                                                                                                                                                                                                      日期

                                                                                                                                                                                                      Date

                                                                                                                                                                                                      描述

                                                                                                                                                                                                      Description

                                                                                                                                                                                                      作者

                                                                                                                                                                                                      Author

                                                                                                                                                                                                      初始草稿

                                                                                                                                                                                                      inception draft

                                                                                                                                                                                                      1月 10, 2031

                                                                                                                                                                                                      Jan 10, 2031

                                                                                                                                                                                                      初稿。主要在阐述过程中进行提炼。

                                                                                                                                                                                                      First draft. To be refined primarily during elaboration.

                                                                                                                                                                                                      克雷格·拉曼

                                                                                                                                                                                                      Craig Larman

                                                                                                                                                                                                          



                                                                                                                                                                                                      介绍

                                                                                                                                                                                                      Introduction

                                                                                                                                                                                                      我们设想了下一代容错销售点 (POS) 应用程序 NextGen POS,它可以灵活地支持不同的客户业务规则、多种终端和用户界面机制,并与多个第三方支持系统集成。

                                                                                                                                                                                                      We envision a next generation fault-tolerant point-of-sale (POS) application, NextGen POS, with the flexibility to support varying customer business rules, multiple terminal and user interface mechanisms, and integration with multiple third-party supporting systems.

                                                                                                                                                                                                      此示例中的分析是说明性的,但只是虚构的。

                                                                                                                                                                                                      The analysis in this example is illustrative, but fictitious.



                                                                                                                                                                                                      定位

                                                                                                                                                                                                      Positioning

                                                                                                                                                                                                      商机

                                                                                                                                                                                                      Business Opportunity

                                                                                                                                                                                                      现有的 POS 产品在不同的业务规则和不同的网络设计(例如,瘦客户端与否;2 层、3 层或 4 层体系结构)方面无法适应客户的业务。此外,随着终端和业务的增长,它们不能很好地扩展。而且,没有一个可以在在线或离线模式下工作,根据故障动态适应。没有一个能轻松与许多第三方系统集成。没有一个项目允许使用新的终端技术,例如移动 PDA。市场对这种僵化的状况感到不满,并要求一种能够纠正这种情况的 POS。

                                                                                                                                                                                                      Existing POS products are not adaptable to the customer's business, in terms of varying business rules and varying network designs (for example, thin client or not; 2, 3, or 4-tier architectures). In addition, they do not scale well as terminals and business increase. And, none can work in either on-line or off-line mode, dynamically adapting depending on failures. None easily integrate with many third-party systems. None allow for new terminal technologies such as mobile PDAs. There is marketplace dissatisfaction with this inflexible state of affairs, and demand for a POS that rectifies this.

                                                                                                                                                                                                      问题陈述

                                                                                                                                                                                                      Problem Statement

                                                                                                                                                                                                      传统的 POS 系统不灵活、不容错且难以与第三方系统集成。这会导致及时的销售处理、制定与软件不匹配的改进流程以及准确及时的会计和库存数据以支持测量和规划等问题。这会影响收银员、商店经理、系统管理员和公司管理层。

                                                                                                                                                                                                      Traditional POS systems are inflexible, fault intolerant, and difficult to integrate with third-party systems. This leads to problems in timely sales processing, instituting improved processes that don't match the software, and accurate and timely accounting and inventory data to support measurement and planning, among other concerns. This affects cashiers, store managers, system administrators, and corporate management.

                                                                                                                                                                                                      产品定位声明

                                                                                                                                                                                                      Product Position Statement

                                                                                                                                                                                                      简要总结了该系统的适用对象、其突出特点以及它与竞争对手的区别。

                                                                                                                                                                                                      Terse summary of who the system is for, its outstanding features, and what differentiates it from the competition.

                                                                                                                                                                                                      替代方案和竞争...

                                                                                                                                                                                                      Alternatives and Competition...

                                                                                                                                                                                                      利益相关者描述

                                                                                                                                                                                                      Stakeholder Descriptions

                                                                                                                                                                                                      了解玩家是谁,以及他们的问题。

                                                                                                                                                                                                      Understand who the players are, and their problems.



                                                                                                                                                                                                      市场人口统计...

                                                                                                                                                                                                      Market Demographics...

                                                                                                                                                                                                      利益干系人(非用户)摘要...

                                                                                                                                                                                                      Stakeholder (Non-User) Summary...

                                                                                                                                                                                                      用户摘要...

                                                                                                                                                                                                      User Summary...

                                                                                                                                                                                                      利益相关者的关键高层目标和问题

                                                                                                                                                                                                      Key High-Level Goals and Problems of the Stakeholders

                                                                                                                                                                                                      与主题专家和其他利益相关者一起举行的为期一天的需求研讨会,并在多家零售店进行了调查,确定了以下关键目标和问题:

                                                                                                                                                                                                      A one-day requirements workshop with subject matter experts and other stakeholders, and surveys at several retail outlets led to identification of the following key goals and problems:

                                                                                                                                                                                                      整合来自用例的 Actor and Goals List 和 Stakeholder Interests 部分的输入。

                                                                                                                                                                                                      Consolidate input from the Actor and Goals List, and the Stakeholder Interests section of the use cases.



                                                                                                                                                                                                      高级别目标

                                                                                                                                                                                                      High-Level Goal

                                                                                                                                                                                                      优先权

                                                                                                                                                                                                      Priority

                                                                                                                                                                                                      问题和担忧

                                                                                                                                                                                                      Problems and Concerns

                                                                                                                                                                                                      当前解决方案

                                                                                                                                                                                                      Current Solutions

                                                                                                                                                                                                      快速、强大、集成的销售处理

                                                                                                                                                                                                      Fast, robust, integrated sales processing

                                                                                                                                                                                                      high

                                                                                                                                                                                                      随着负载的增加而降低速度。

                                                                                                                                                                                                      Reduced speed as load increases.

                                                                                                                                                                                                      如果组件出现故障,则销售处理能力的损失。

                                                                                                                                                                                                      Loss of sales processing capability if components fail.

                                                                                                                                                                                                      由于未与现有会计、库存和 HR 系统集成,会计和其他系统缺乏最新和准确的信息。导致测量和规划困难。

                                                                                                                                                                                                      Lack of up-to-date and accurate information from accounting and other systems due to non-integration with existing accounting, inventory, and HR systems. Leads to difficulties in measuring and planning.

                                                                                                                                                                                                      无法根据独特的业务需求自定义业务规则。

                                                                                                                                                                                                      Inability to customize business rules to unique business requirements.

                                                                                                                                                                                                      难以添加新的终端或用户界面类型(例如,移动 PDA)。

                                                                                                                                                                                                      Difficulty in adding new terminal or user interface types (for example, mobile PDAs).

                                                                                                                                                                                                      现有的 POS 商品提供基本的销售处理,但无法解决这些问题。

                                                                                                                                                                                                      Existing POS products provide basic sales processing, but do not address these problems.

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .



                                                                                                                                                                                                      用户级目标

                                                                                                                                                                                                      User-Level Goals

                                                                                                                                                                                                      用户(和外部系统)需要一个系统来实现这些目标:

                                                                                                                                                                                                      The users (and external systems) need a system to fulfill these goals:

                                                                                                                                                                                                      这可能是在用例建模期间创建的 Actor-Goal List,也可以是更简洁的摘要。

                                                                                                                                                                                                      This may be the Actor-Goal List created during use-case modeling, or a more terse summary.



                                                                                                                                                                                                      • 收银员: 处理销售、处理退货、兑现、兑现

                                                                                                                                                                                                      • Cashier: process sales, handle returns, cash in, cash out

                                                                                                                                                                                                      • 系统管理员: 管理用户, 管理安全性, 管理系统表

                                                                                                                                                                                                      • System administrator: manage users, manage security, manage system tables

                                                                                                                                                                                                      • 经理: 启动、关闭

                                                                                                                                                                                                      • Manager: start up, shut down

                                                                                                                                                                                                      • 销售活动系统: 分析销售数据

                                                                                                                                                                                                      • Sales activity system: analyze sales data

                                                                                                                                                                                                      用户环境...

                                                                                                                                                                                                      User Environment…

                                                                                                                                                                                                      产品概述

                                                                                                                                                                                                      Product Overview

                                                                                                                                                                                                      产品视角

                                                                                                                                                                                                      Product Perspective

                                                                                                                                                                                                      NextGen POS 通常位于商店中;如果使用移动终端,它们将靠近商店网络,无论是在内部还是靠近外部。它将为用户提供服务,并与其他系统协作,如图 Vision-1 所示。

                                                                                                                                                                                                      The NextGen POS will usually reside in stores; if mobile terminals are used, they will be in close proximity to the store network, either inside or close outside. It will provide services to users, and collaborate with other systems, as indicated in Figure Vision-1.

                                                                                                                                                                                                      图视觉 - 1.NextGen POS 系统上下文图



                                                                                                                                                                                                      从用例图中总结。

                                                                                                                                                                                                      Summarized from the use case diagram.



                                                                                                                                                                                                      上下文图有不同的格式和不同的细节,但都显示了与系统相关的主要外部参与者。

                                                                                                                                                                                                      Context diagrams come in different formats with varying detail, but all show the major external actors related to a system.



                                                                                                                                                                                                      优势总结

                                                                                                                                                                                                      Summary of Benefits

                                                                                                                                                                                                      支持功能

                                                                                                                                                                                                      Supporting Feature

                                                                                                                                                                                                      利益相关者的利益

                                                                                                                                                                                                      Stakeholder Benefit

                                                                                                                                                                                                      从功能上讲,该系统将提供销售组织所需的所有常见服务,包括销售捕获、付款授权、退货处理等。

                                                                                                                                                                                                      Functionally, the system will provide all the common services a sales organization requires, including sales capture, payment authorization, return handling, and so forth.

                                                                                                                                                                                                      自动化、快速的销售点服务。

                                                                                                                                                                                                      Automated, fast point-of-sale services.

                                                                                                                                                                                                      自动检测故障,对不可用的服务切换到本地离线处理。

                                                                                                                                                                                                      Automatic detection of failures, switching to local offline processing for unavailable services.

                                                                                                                                                                                                      当外部组件出现故障时,继续进行销售处理。

                                                                                                                                                                                                      Continued sales processing when external components fail.

                                                                                                                                                                                                      销售处理期间各个场景点的可插拔业务规则。

                                                                                                                                                                                                      Pluggable business rules at various scenario points during sales processing.

                                                                                                                                                                                                      灵活的业务逻辑配置。

                                                                                                                                                                                                      Flexible business logic configuration.

                                                                                                                                                                                                      使用行业标准协议与第三方系统进行实时交易。

                                                                                                                                                                                                      Real-time transactions with third-party systems, using industry standard protocols.

                                                                                                                                                                                                      及时、准确的销售、会计和库存信息,以支持测量和规划。

                                                                                                                                                                                                      Timely, accurate sales, accounting, and inventory information, to support measuring and planning.

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .

                                                                                                                                                                                                      . . .



                                                                                                                                                                                                      与 Actor-Goal 列表类似,此表涉及目标、收益和解决方案,但在更高级别上,不仅与用例相关。

                                                                                                                                                                                                      Similar to the Actor-Goal list, this table relates goals, benefits, and solutions, but at a higher level not solely related to use cases.



                                                                                                                                                                                                      它总结了产品的价值和差异化品质。

                                                                                                                                                                                                      It summarizes the value and differentiating qualities of the product.



                                                                                                                                                                                                      假设和依赖关系...

                                                                                                                                                                                                      Assumptions and Dependencies...

                                                                                                                                                                                                      成本和定价...

                                                                                                                                                                                                      Cost and Pricing...

                                                                                                                                                                                                      许可和安装...

                                                                                                                                                                                                      Licensing and Installation...

                                                                                                                                                                                                      系统功能总结

                                                                                                                                                                                                      Summary of System Features

                                                                                                                                                                                                      如下所述,系统功能是总结功能的简洁格式。

                                                                                                                                                                                                      As discussed below, system features are a terse format to summarize functionality.



                                                                                                                                                                                                      • 销售捕获

                                                                                                                                                                                                      • sales capture

                                                                                                                                                                                                      • 付款授权(信用卡、借记卡、支票)

                                                                                                                                                                                                      • payment authorization (credit, debit, check)

                                                                                                                                                                                                      • 用户、安全性、代码和常量表等的系统管理。

                                                                                                                                                                                                      • system administration for users, security, code and constants tables, and so forth.

                                                                                                                                                                                                      • 外部组件故障时自动进行离线销售处理

                                                                                                                                                                                                      • automatic offline sales processing when external components fail

                                                                                                                                                                                                      • 根据行业标准,与第三方系统进行实时交易,包括库存、会计、人力资源、税务计算器和支付授权服务

                                                                                                                                                                                                      • real-time transactions, based on industry standards, with third-party systems, including inventory, accounting, human resources, tax calculators, and payment authorization services

                                                                                                                                                                                                      • 在处理场景中的固定公共点定义和执行定制的 “可插拔” 业务规则

                                                                                                                                                                                                      • definition and execution of customized "pluggable" business rules at fixed, common points in the processing scenarios

                                                                                                                                                                                                      其他要求和约束

                                                                                                                                                                                                      Other Requirements and Constraints

                                                                                                                                                                                                      包括设计约束、可用性、可靠性、性能、可支持性、设计约束、文档、打包等:请参阅补充规范和用例。

                                                                                                                                                                                                      Including design constraints, usability, reliability, performance, supportability, design constraints, documentation, packaging, and so forth: See the Supplementary Specification and use cases.



                                                                                                                                                                                                        7.7. 释经评注:异象

                                                                                                                                                                                                        7.7. Commentary: Vision

                                                                                                                                                                                                        当有人加入项目时,能够说“欢迎!请在项目网站上阅读 7 页的愿景。有一个简要描述项目的执行摘要也很有用,作为主要参与者建立项目的共同愿景的背景。

                                                                                                                                                                                                        When someone joins the project, it is useful to be able to say, "Welcome! Please go read the 7-page Vision at the project website." It is also useful to have an executive summary that briefly describes the project, as a context for the major players to establish a common vision of the project.

                                                                                                                                                                                                        愿景不应冗长,也不应试图详细描述确定的要求。它应该总结 Use-Case Model 和 Supplementary Specification 中的一些信息。

                                                                                                                                                                                                        The Vision should not be long, nor should it attempt to describe firm requirements in detail. And it should summarize some of the information in the Use-Case Model and Supplementary Specification.

                                                                                                                                                                                                        利益相关者的关键高层目标和问题

                                                                                                                                                                                                        The Key High-Level Goals and Problems of the Stakeholders

                                                                                                                                                                                                        本节总结了高层次的目标和问题,通常高于特定用例,并揭示了可能属于一个用例或跨越多个用例的重要非功能性和质量目标,例如:

                                                                                                                                                                                                        This section summarizes the goals and problems at a high leveloften higher than specific use casesand reveals important non-functional and quality goals that may belong to one use case or span many, such as:

                                                                                                                                                                                                        • 我们需要容错的销售处理。

                                                                                                                                                                                                        • We need fault-tolerant sales processing.

                                                                                                                                                                                                        • 我们需要自定义业务规则的能力。

                                                                                                                                                                                                        • We need the ability to customize the business rules.

                                                                                                                                                                                                        指南:有哪些便利化方法?

                                                                                                                                                                                                        特别是在高级问题定义和目标识别等活动中,创造性的调查性小组工作才会发生。以下是一些有用的小组促进技术,用于发现根本问题和目标,并支持想法的产生和优先级排序:思维导图、产品愿景框创建、鱼骨图、帕累托图、头脑风暴、多重投票、点投票、名义小组流程、脑力写作和兴趣分组。在 Web 上查看它们。我更喜欢在同一个研讨会中应用其中的几个,以便从不同角度发现常见问题和需求。

                                                                                                                                                                                                        It is especially during activities such as high-level problem definition and goal identification that creative, investigative group work occurs. Here are some useful group facilitation techniques to discover root problems and goals, and support idea generation and prioritization: mind mapping, product vision box creation, fishbone diagrams, pareto diagrams, brainstorming, multi-voting, dot voting, nominal group process, brainwriting, and affinity grouping. Check them out on the Web. I prefer to apply several of these during the same workshop, to discover common problems and requirements from different angles.

                                                                                                                                                                                                        系统功能总结

                                                                                                                                                                                                        Summary of System Features

                                                                                                                                                                                                        在 Vision 中仅列出用例名称不足以掌握主要功能。为什么?

                                                                                                                                                                                                        Simply listing the use case names is not sufficient in the Vision to grasp the major features. Why?

                                                                                                                                                                                                        • 太详细或低级。人们想要一个关于大想法的简短总结。可能有 30 或 50 个用例。

                                                                                                                                                                                                        • Too detailed or low-level. People want a short summary of the big ideas. There could be 30 or 50 use cases.

                                                                                                                                                                                                        • 用例名称可以隐藏利益相关者真正想知道的有趣主要功能。例如,假设自动付款授权功能的描述嵌入在 Process Sale 用例中。用例名称列表的读者无法判断系统是否会进行支付授权。

                                                                                                                                                                                                        • The use case name can hide interesting major features stakeholders really want to know about. For example, suppose that the description of automated payment authorization functionality is embedded in the Process Sale use case. A reader of a list of use case names can't tell if the system will do payment authorization.

                                                                                                                                                                                                        • 一些值得注意的功能跨越或与用例正交。例如,在第一次 NextGen 需求研讨会期间,有人可能会说“系统应该能够与现有的第三方会计、库存和税务计算系统进行交互”。

                                                                                                                                                                                                        • Some noteworthy features span or are orthogonal to the use cases. For example, during the first NextGen requirements workshop, someone might say "The system should be able to interact with existing third-party accounting, inventory, and tax calculation systems."

                                                                                                                                                                                                        因此,表示系统功能的另一种补充方式是使用功能,或者更具体地说,在此上下文中使用系统功能,它们是总结系统功能的高级简洁语句。更正式地说,在 UP 中,系统功能是“由系统提供的外部可观察服务,直接满足利益相关者的需求”[Kruchten00]。

                                                                                                                                                                                                        Therefore, an alternative, complementary way to express system functions is with features, or more specifically in this context, system features, which are high-level, terse statements summarizing system functions. More formally, in the UP, a system feature is "an externally observable service provided by the system which directly fulfills a stakeholder need" [Kruchten00].

                                                                                                                                                                                                        定义

                                                                                                                                                                                                        Definition

                                                                                                                                                                                                        特征是系统可以执行的行为功能。他们应该通过这个语言测试:

                                                                                                                                                                                                        Features are behavioral functions a system can do. They should pass this linguistic test:

                                                                                                                                                                                                        系统<特征 X>。

                                                                                                                                                                                                        The system does <feature X>.



                                                                                                                                                                                                        例如:

                                                                                                                                                                                                        For example:

                                                                                                                                                                                                        系统进行支付授权

                                                                                                                                                                                                        The system does payment authorization.

                                                                                                                                                                                                        功能性系统特性将与各种非功能性需求和约束进行对比,例如:“系统必须在 Linux 上运行,必须具有 24/7 可用性,并且必须具有触摸屏界面。请注意,这些未通过语言测试;例如,系统执行 Linux

                                                                                                                                                                                                        Functional system features are to be contrasted with various kinds of non-functional requirements and constraints, such as: "The system must run on Linux, must have 24/7 availability, and must have a touch-screen interface." Note that these fail the linguistic test; for example, the system does Linux.

                                                                                                                                                                                                        指南:如何编写功能列表?

                                                                                                                                                                                                        简洁在愿景中确实很好,在任何文件中都是好的。

                                                                                                                                                                                                        Terse is good in the Visionindeed, in any document.

                                                                                                                                                                                                        下面是一个高级功能示例,适用于大型多系统项目,其中 POS 只是一个元素:

                                                                                                                                                                                                        Here is a features example at a high level, for a large multi-system project of which the POS is just one element:

                                                                                                                                                                                                        主要功能包括:

                                                                                                                                                                                                        The major features include:

                                                                                                                                                                                                        • POS 服务

                                                                                                                                                                                                        • POS services

                                                                                                                                                                                                        • 库存管理

                                                                                                                                                                                                        • Inventory management

                                                                                                                                                                                                        • 基于 Web 的购物

                                                                                                                                                                                                        • Web-based shopping

                                                                                                                                                                                                        通常组织系统功能的两级层次结构。但在 Vision 文档中,超过两个级别会导致过多的细节;Vision 中系统特性的重点是总结功能,而不是将其分解为一长串细粒度的元素。就细节而言,一个合理的例子:

                                                                                                                                                                                                        It is common to organize a two-level hierarchy of system features. But in the Vision document more than two levels leads to excessive detail; the point of system features in the Vision is to summarize the functionality, not decompose it into a long list of fine-grained elements. A reasonable example in terms of detail:

                                                                                                                                                                                                        主要功能包括:

                                                                                                                                                                                                        The major features include:

                                                                                                                                                                                                        • POS 服务:

                                                                                                                                                                                                          • 销售捕获

                                                                                                                                                                                                          • 支付授权

                                                                                                                                                                                                        • POS services:

                                                                                                                                                                                                          • sales capture

                                                                                                                                                                                                          • payment authorization

                                                                                                                                                                                                        • 库存管理:

                                                                                                                                                                                                          • 自动重新排序

                                                                                                                                                                                                        • Inventory management:

                                                                                                                                                                                                          • automatic reordering

                                                                                                                                                                                                        Vision 应该包含多少个系统功能?

                                                                                                                                                                                                        How many system features should the Vision contain?

                                                                                                                                                                                                        指引

                                                                                                                                                                                                        Guideline

                                                                                                                                                                                                        特征少于 10 个的愿景是可取的,但无法快速掌握。如果更多,请考虑对特征进行分组和抽象化。

                                                                                                                                                                                                        A Vision with less than 10 features is desirablemore can't be quickly grasped. If more, consider grouping and abstracting the features.



                                                                                                                                                                                                        指南:我们应该复制异象中的其他要求吗?

                                                                                                                                                                                                        Guideline: Should We Duplicate Other Requirements in the Vision?

                                                                                                                                                                                                        在 Vision 中,系统功能简要总结了功能要求,通常在用例中详细说明。同样,Vision 可以总结补充规范中详述的其他要求(例如,可靠性和可用性)。但要小心,避免走上重复自己的道路。

                                                                                                                                                                                                        In the Vision, system features briefly summarize functional requirements often detailed in the use cases. Likewise, the Vision can summarize other requirements (for example, reliability and usability) that are detailed in the Supplementary Specification. But be careful to avoid going down the path of repeating yourself.

                                                                                                                                                                                                        指引

                                                                                                                                                                                                        Guideline

                                                                                                                                                                                                        对于其他要求,请避免在愿景和补充规范 (SS) 中重复或接近重复。相反,只在 SS 中记录它们。在 Vision 中,将读者引导至 SS 以了解其他要求。

                                                                                                                                                                                                        For other requirements, avoid their duplication or near-duplication in both the Vision and Supplementary Specification (SS). Rather, record them only in the SS. In the Vision, direct the reader to the SS for the other requirements.



                                                                                                                                                                                                        指南:您应该先编写愿景还是用例?

                                                                                                                                                                                                        Guideline: Should You Write the Vision or Use Cases First?

                                                                                                                                                                                                        对顺序严格来说是没有用的。当开发人员协作创建不同的需求工件时,会出现一种协同作用,其中处理一个工件会影响并帮助澄清另一个工件。不过,建议的顺序是:

                                                                                                                                                                                                        It isn't useful to be rigid about the order. While developers are collaborating to create different requirements artifacts, a synergy emerges in which working on one artifact influences and helps clarify another. Nevertheless, a suggested sequence is:

                                                                                                                                                                                                        1. 写一份简短的愿景初稿。

                                                                                                                                                                                                        2. Write a brief first draft of the Vision.

                                                                                                                                                                                                        3. 按名称确定用户目标和支持使用案例。

                                                                                                                                                                                                        4. Identify user goals and the supporting use cases by name.

                                                                                                                                                                                                        5. 详细编写一些用例,然后开始补充规范。

                                                                                                                                                                                                        6. Write some use cases in detail, and start the Supplementary Specification.

                                                                                                                                                                                                        7. 优化 Vision,总结其中的信息。

                                                                                                                                                                                                        8. Refine the Vision, summarizing information from these.

                                                                                                                                                                                                          7.8. NextGen 示例:(部分)词汇表

                                                                                                                                                                                                          7.8. NextGen Example: A (Partial) Glossary

                                                                                                                                                                                                          词汇表

                                                                                                                                                                                                          Glossary

                                                                                                                                                                                                          修订历史记录

                                                                                                                                                                                                          Revision History

                                                                                                                                                                                                          版本

                                                                                                                                                                                                          Version

                                                                                                                                                                                                          日期

                                                                                                                                                                                                          Date

                                                                                                                                                                                                          描述

                                                                                                                                                                                                          Description

                                                                                                                                                                                                          作者

                                                                                                                                                                                                          Author

                                                                                                                                                                                                          初始草稿

                                                                                                                                                                                                          Inception draft

                                                                                                                                                                                                          1月 10, 2031

                                                                                                                                                                                                          Jan 10, 2031

                                                                                                                                                                                                          初稿。主要在阐述过程中进行提炼。

                                                                                                                                                                                                          First draft. To be refined primarily during elaboration.

                                                                                                                                                                                                          克雷格·拉曼

                                                                                                                                                                                                          Craig Larman

                                                                                                                                                                                                              



                                                                                                                                                                                                          定义

                                                                                                                                                                                                          Definitions

                                                                                                                                                                                                          术语

                                                                                                                                                                                                          Term

                                                                                                                                                                                                          定义和信息

                                                                                                                                                                                                          Definition and Information

                                                                                                                                                                                                          格式

                                                                                                                                                                                                          Format

                                                                                                                                                                                                          验证规则

                                                                                                                                                                                                          Validation Rules

                                                                                                                                                                                                          别名

                                                                                                                                                                                                          Aliases

                                                                                                                                                                                                          项目

                                                                                                                                                                                                          item

                                                                                                                                                                                                          待售产品或服务

                                                                                                                                                                                                          A product or service for sale

                                                                                                                                                                                                             

                                                                                                                                                                                                          支付授权

                                                                                                                                                                                                          payment authorization

                                                                                                                                                                                                          由外部付款授权服务验证他们将向卖家付款或保证付款。

                                                                                                                                                                                                          Validation by an external payment authorization service that they will make or guarantee the payment to the seller.

                                                                                                                                                                                                             

                                                                                                                                                                                                          付款授权请求

                                                                                                                                                                                                          payment authorization request

                                                                                                                                                                                                          以电子方式发送到授权服务的元素组合,通常为 char 数组。元素包括:商店 ID、客户账号、金额和时间戳。

                                                                                                                                                                                                          A composite of elements electronically sent to an authorization service, usually as a char array. Elements include: store ID, customer account number, amount, and timestamp.

                                                                                                                                                                                                             

                                                                                                                                                                                                          UPC

                                                                                                                                                                                                          UPC

                                                                                                                                                                                                          标识商品的数字代码。通常用放置在产品上的条形码进行符号化。

                                                                                                                                                                                                          Numeric code that identifies a product. Usually symbolized with a bar code placed on products.

                                                                                                                                                                                                          有关格式和验证的详细信息,请参阅 www.uc-council.org

                                                                                                                                                                                                          See www.uc-council.org for details of format and validation.

                                                                                                                                                                                                          几个子部分的 12 位代码。

                                                                                                                                                                                                          12-digit code of several subparts.

                                                                                                                                                                                                          数字 12 i s 校验位。

                                                                                                                                                                                                          Digit 12 i s a check digit.

                                                                                                                                                                                                          通用产品代码

                                                                                                                                                                                                          Universal Product Code

                                                                                                                                                                                                             





                                                                                                                                                                                                            7.9. 注释:词汇表(数据字典)

                                                                                                                                                                                                            7.9. Commentary: Glossary (Data Dictionary)

                                                                                                                                                                                                            在最简单的形式中,词汇表是一份值得注意的术语及其定义的列表。令人惊讶的是,一个术语,通常是技术性的或特定于该领域的术语,不同的利益相关者会以略有不同的方式使用;这需要解决,以减少沟通问题和模棱两可的需求。

                                                                                                                                                                                                            In its simplest form, the Glossary is a list of noteworthy terms and their definitions. It is surprisingly common that a term, often technical or particular to the domain, will be used in slightly different ways by different stakeholders; this needs to be resolved to reduce problems in communication and ambiguous requirements.

                                                                                                                                                                                                            指引

                                                                                                                                                                                                            Guideline

                                                                                                                                                                                                            尽早开始 Glossary。它将很快成为与细粒度元素相关详细信息的有用存储库。

                                                                                                                                                                                                            Start the Glossary early. It will quickly become a useful repository of detailed information related to fine-grained elements.



                                                                                                                                                                                                            作为数据字典的词汇表

                                                                                                                                                                                                            Glossary as Data Dictionary

                                                                                                                                                                                                            在 UP 中,Glossary 还扮演着数据字典的角色,数据字典是记录有关数据(即元数据)的文档。在开始时,词汇表应该是术语和描述的简单文档。在细化过程中,它可能会扩展为数据字典。

                                                                                                                                                                                                            In the UP, the Glossary also plays the role of a data dictionary, a document that records data about the datathat is, metadata. During inception the glossary should be a simple document of terms and descriptions. During elaboration, it may expand into a data dictionary.

                                                                                                                                                                                                            术语属性可能包括:

                                                                                                                                                                                                            Term attributes could include:

                                                                                                                                                                                                            • 别名

                                                                                                                                                                                                            • aliases

                                                                                                                                                                                                            • 描述

                                                                                                                                                                                                            • description

                                                                                                                                                                                                            • 格式(类型、长度、单位)

                                                                                                                                                                                                            • format (type, length, unit)

                                                                                                                                                                                                            • 与其他元素的关系

                                                                                                                                                                                                            • relationships to other elements

                                                                                                                                                                                                            • 值范围

                                                                                                                                                                                                            • range of values

                                                                                                                                                                                                            • 验证规则

                                                                                                                                                                                                            • validation rules

                                                                                                                                                                                                            请注意,Glossary 中的值范围和验证规则构成了对系统行为有影响的要求。

                                                                                                                                                                                                            Note that the range of values and validation rules in the Glossary constitute requirements with implications on the behavior of the system.



                                                                                                                                                                                                            指南:我们可以使用 Glossary 来记录复合术语吗?

                                                                                                                                                                                                            Guideline: Can We use the Glossary to Record Composite Terms?

                                                                                                                                                                                                            词汇表不仅适用于 “product price” 等原子术语。它可以而且应该包括复合元素,例如 “sale” (包括其他元素,例如日期和位置) 和昵称,用于描述用例中参与者之间传输的数据集合。例如,在 Process Sale 用例中,请考虑以下语句:

                                                                                                                                                                                                            The Glossary is not only for atomic terms such as "product price." It can and should include composite elements such as "sale" (which includes other elements, such as date and location) and nicknames used to describe a collection of data transmitted between actors in the use cases. For example, in the Process Sale use case, consider the following statement:

                                                                                                                                                                                                            系统向外部 Payment Authorization Service 发送支付授权请求,并请求支付审批。

                                                                                                                                                                                                            System sends payment authorization request to an external Payment Authorization Service, and requests payment approval.

                                                                                                                                                                                                            “支付授权请求”是数据聚合的昵称,需要在术语表中解释。

                                                                                                                                                                                                            "Payment authorization request" is a nickname for an aggregate of data, which needs to be explained in the Glossary.

                                                                                                                                                                                                              7.10. NextGen 示例:业务规则(域规则)

                                                                                                                                                                                                              7.10. NextGen Example: Business Rules (Domain Rules)

                                                                                                                                                                                                              域规则

                                                                                                                                                                                                              Domain Rules

                                                                                                                                                                                                              修订历史记录

                                                                                                                                                                                                              Revision History

                                                                                                                                                                                                              版本

                                                                                                                                                                                                              Version

                                                                                                                                                                                                              日期

                                                                                                                                                                                                              Date

                                                                                                                                                                                                              描述

                                                                                                                                                                                                              Description

                                                                                                                                                                                                              作者

                                                                                                                                                                                                              Author

                                                                                                                                                                                                              初始草稿

                                                                                                                                                                                                              inception draft

                                                                                                                                                                                                              1月 10, 2031

                                                                                                                                                                                                              Jan 10, 2031

                                                                                                                                                                                                              初稿。主要在阐述过程中进行提炼。

                                                                                                                                                                                                              First draft. To be refined primarily during elaboration.

                                                                                                                                                                                                              克雷格·拉曼

                                                                                                                                                                                                              Craig Larman

                                                                                                                                                                                                                  



                                                                                                                                                                                                              规则列表

                                                                                                                                                                                                              Rule List

                                                                                                                                                                                                              (另请参阅补充规范中单独的特定于应用程序的规则。

                                                                                                                                                                                                              (See also the separate Application-specific Rules in the Supplementary Specification.)

                                                                                                                                                                                                              身份证

                                                                                                                                                                                                              ID

                                                                                                                                                                                                              统治

                                                                                                                                                                                                              Rule

                                                                                                                                                                                                              多变性

                                                                                                                                                                                                              Changeability

                                                                                                                                                                                                              Source

                                                                                                                                                                                                              规则 1

                                                                                                                                                                                                              RULE1

                                                                                                                                                                                                              信用付款需要签名。

                                                                                                                                                                                                              Signature required for credit payments.

                                                                                                                                                                                                              买家“签名”将继续是必需的,但在 2 年内,我们的大多数客户都希望在数字采集设备上进行签名采集,而在 5 年内,我们预计会有需求支持美国法律现在支持的新的唯一数字代码“签名”。

                                                                                                                                                                                                              Buyer "signature" will continue to be required, but within 2 years most of our customers want signature capture on a digital capture device, and within 5 years we expect there to be demand for support of the new unique digital code "signature" now supported by USA law.

                                                                                                                                                                                                              几乎所有信用授权公司的政策。

                                                                                                                                                                                                              The policy of virtually all credit authorization companies.

                                                                                                                                                                                                              规则 2

                                                                                                                                                                                                              RULE2

                                                                                                                                                                                                              税务规则。销售需要加税。有关当前详细信息,请参阅政府法规。

                                                                                                                                                                                                              Tax rules. Sales require added taxes. See government statutes for current details.

                                                                                                                                                                                                              高。各级政府的税法每年都会发生变化。

                                                                                                                                                                                                              High. Tax laws change annually, at all government levels.

                                                                                                                                                                                                              法律

                                                                                                                                                                                                              law

                                                                                                                                                                                                              规则 3

                                                                                                                                                                                                              RULE3

                                                                                                                                                                                                              贷记付款冲销只能作为贷记支付到买家的贷记账户,而不能以现金支付。

                                                                                                                                                                                                              Credit payment reversals may only be paid as a credit to the buyer's credit account, not as cash.

                                                                                                                                                                                                              Low

                                                                                                                                                                                                              信用授权公司政策

                                                                                                                                                                                                              credit authorization company policy





                                                                                                                                                                                                                7.11. 注释:域规则

                                                                                                                                                                                                                7.11. Commentary: Domain Rules

                                                                                                                                                                                                                域规则 [Ross97GK00] 规定了域或企业的运作方式。它们不是任何一个应用程序的要求,尽管应用程序的要求通常受域规则的影响。公司策略、物理法则(例如石油如何在地动)和政府法律是常见的域规则。

                                                                                                                                                                                                                Domain rules [Ross97, GK00] dictate how a domain or business may operate. They are not requirements of any one application, although an application's requirements are often influenced by domain rules. Company policies, physical laws (such as how oil flows underground), and government laws are common domain rules.

                                                                                                                                                                                                                它们通常被称为业务规则,这是最常见的类型,但这个术语很糟糕,因为许多软件应用程序用于非业务问题,例如天气模拟或军事物流。天气模拟具有与物理定律和关系相关的 “域规则”,这些规则会影响应用程序要求。

                                                                                                                                                                                                                They are commonly called business rules, which is the most common type, but that term is poor, as many software applications are for non-business problems, such as weather simulation or military logistics. A weather simulation has "domain rules," related to physical laws and relationships, that influence the application requirements.

                                                                                                                                                                                                                在单独的独立于应用程序的工件(UP 称为 Business Rules 工件)中识别和记录域规则非常有用,这样就可以在整个组织和项目之间共享和重用此分析,而不是隐藏在特定于项目的文档中。

                                                                                                                                                                                                                It's useful to identify and record domain rules in a separate application-independent artifactwhat the UP calls the Business Rules artifactso that this analysis can be shared and reused across the organization and across projects, rather than buried within a project-specific document.

                                                                                                                                                                                                                这些规则可以帮助澄清用例中的歧义,这些用例强调故事的流程而不是细节。例如,在 NextGen POS 中,如果有人询问是否应该使用替代方案编写 Process Sale 用例,以允许在没有签名捕获的情况下进行信用支付,则有一个业务规则 (RULE1) 阐明了任何信用授权公司是否不允许这样做。

                                                                                                                                                                                                                The rules can help clarify ambiguities in the use cases, which emphasize the flow of the story rather than the details. For example, in the NextGen POS, if someone asks if the Process Sale use case should be written with an alternative to allow credit payments without signature capture, there is a business rule (RULE1) that clarifies whether this will not be allowed by any credit authorization company.

                                                                                                                                                                                                                  7.12. 过程:迭代方法中的进化要求

                                                                                                                                                                                                                  7.12. Process: Evolutionary Requirements in Iterative Methods

                                                                                                                                                                                                                  正如迭代方法(包括 UP)中反复强调的那样(因为它很关键,但经常被忽视),这些需求在项目开始时并没有得到充分的分析和编写。相反,它们在一系列需求研讨会(例如)中不断发展,其中穿插着早期生产质量的编程和测试。早期开发的反馈可以改进规范。

                                                                                                                                                                                                                  As repeatedly stressed (as it's critical, yet too often ignored) in iterative methods, including the UP, these requirements are not fully analyzed and written near the start of the project. Rather, they evolve over a series of requirements workshops (for example), interspersed with early production-quality programming and testing. Feedback from early development refines the specifications.



                                                                                                                                                                                                                  与用例章节一样,表 7.1 总结了 UP 中的工件示例及其可能的时序。通常,大多数需求工件都是在开始时开始的,并且主要在细化过程中开发。

                                                                                                                                                                                                                  As in the use case chapter, Table 7.1 summarizes a sample of artifacts and their possible timing in the UP. Usually, most requirements artifacts are started in inception and primarily developed during elaboration.

                                                                                                                                                                                                                  表 7.1.UP 伪影和计时示例。s - 开始;R - 优化

                                                                                                                                                                                                                  学科

                                                                                                                                                                                                                  Discipline

                                                                                                                                                                                                                  人工制品

                                                                                                                                                                                                                  Artifact

                                                                                                                                                                                                                  因塞普。

                                                                                                                                                                                                                  Incep.

                                                                                                                                                                                                                  埃拉布。

                                                                                                                                                                                                                  Elab.

                                                                                                                                                                                                                  常量。

                                                                                                                                                                                                                  Const.

                                                                                                                                                                                                                  反式。

                                                                                                                                                                                                                  Trans.

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  迭 代

                                                                                                                                                                                                                  Iteration

                                                                                                                                                                                                                  I1

                                                                                                                                                                                                                  E1..中文

                                                                                                                                                                                                                  E1..En

                                                                                                                                                                                                                  C1..快递 之 家

                                                                                                                                                                                                                  C1..Cn

                                                                                                                                                                                                                  T1..T2 航站楼

                                                                                                                                                                                                                  T1..T2

                                                                                                                                                                                                                  业务建模

                                                                                                                                                                                                                  Business Modeling

                                                                                                                                                                                                                  域模型

                                                                                                                                                                                                                  Domain Model

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  要求

                                                                                                                                                                                                                  Requirements

                                                                                                                                                                                                                  用例模型

                                                                                                                                                                                                                  Use-Case Model

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  视觉

                                                                                                                                                                                                                  Vision

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  补充规格

                                                                                                                                                                                                                  Supplementary Specification

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  词汇表

                                                                                                                                                                                                                  Glossary

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  业务规则

                                                                                                                                                                                                                  Business Rules

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  设计

                                                                                                                                                                                                                  Design

                                                                                                                                                                                                                  设计模型

                                                                                                                                                                                                                  Design Model

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  软件架构文档

                                                                                                                                                                                                                  SW Architecture Document

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                    

                                                                                                                                                                                                                  数据模型

                                                                                                                                                                                                                  Data Model

                                                                                                                                                                                                                   

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  s

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                  r

                                                                                                                                                                                                                   



                                                                                                                                                                                                                  初始

                                                                                                                                                                                                                  Inception

                                                                                                                                                                                                                  利益相关者需要决定该项目是否值得认真调查;真正的调查发生在阐述过程中,而不是开始阶段。在开始时,愿景以某种形式总结了项目想法,以帮助决策者确定是否值得继续,以及从哪里开始。

                                                                                                                                                                                                                  Stakeholders need to decide if the project is worth serious investigation; that real investigation occurs during elaboration, not inception. During inception, the Vision summarizes the project idea in a form to help decision makers determine if it is worth continuing, and where to start.

                                                                                                                                                                                                                  由于大多数需求分析发生在制定过程中,因此补充规范在开始时只应进行轻微的制定,突出暴露重大风险和挑战的值得注意的质量属性(例如,NextGen POS 在外部服务出现故障时必须具有可恢复性)。

                                                                                                                                                                                                                  Since most requirements analysis occurs during elaboration, the Supplementary Specification should be only lightly developed during inception, highlighting noteworthy quality attributes that expose major risks and challenges (for example, the NextGen POS must have recoverability when external services fail).

                                                                                                                                                                                                                  这些工件的输入可以在 inception phase 需求研讨会期间生成。

                                                                                                                                                                                                                  Input into these artifacts could be generated during an inception phase requirements workshop.

                                                                                                                                                                                                                  阐述

                                                                                                                                                                                                                  Elaboration

                                                                                                                                                                                                                  通过细化迭代,“愿景”和愿景得到提炼,基于逐步构建系统的各个部分、适应和在多次开发迭代中举行的多个需求研讨会的反馈。

                                                                                                                                                                                                                  Through the elaboration iterations, the "vision" and the Vision are refined, based upon feedback from incrementally building parts of the system, adapting, and multiple requirements workshops held over several development iterations.

                                                                                                                                                                                                                  通过持续的需求调查和迭代开发,其他需求将变得更加清晰,并且可以记录在补充规范中。

                                                                                                                                                                                                                  Through ongoing requirements investigation and iterative development, the other requirements will become more clear and can be recorded in the Supplementary Specification.

                                                                                                                                                                                                                  在阐述结束时,可以拥有用例、补充规范和愿景,以合理反映稳定的主要功能和其他需要完成交付的要求。尽管如此,补充规范和愿景并不是可以冻结和“签署”作为固定规范的东西;适应而不是僵化是迭代开发和 UP 的核心价值。

                                                                                                                                                                                                                  By the end of elaboration, it is feasible to have use cases, a Supplementary Specification, and a Vision that reasonably reflects the stabilized major features and other requirements to be completed for delivery. Nevertheless, the Supplementary Specification and Vision are not something to freeze and "sign off" on as a fixed specification; adaptationnot rigidityis a core value of iterative development and the UP.

                                                                                                                                                                                                                  澄清一下这个 “冻结签字” 评论:在阐述结束时,与利益相关者就项目剩余部分将做什么达成协议,并就要求和时间表做出承诺(可能是合同承诺)是完全明智的。在某个时候(在 UP 中,阐述的结尾),我们需要一个可靠的 “什么、多少 和 什么时候 ”的概念。从这个意义上说,就要求达成正式协议是正常的,也是意料之中的。对于正式考虑和批准的需求变更,也有必要有一个变更控制流程(UP 中明确的最佳实践之一),而不是混乱和不受控制的变更。

                                                                                                                                                                                                                  To clarify this "frozen sign off" comment: It is perfectly sensibleat the end of elaborationto form an agreement with stakeholders about what will be done in the remainder of the project, and to make commitments (perhaps contractual) regarding requirements and schedule. At some point (the end of elaboration, in the UP), we need a reliable idea of "what, how much, and when." In that sense, a formal agreement on the requirements is normal and expected. It is also necessary to have a change control process (one of the explicit best practices in the UP) for formally considered and approved requirements changes, rather than chaotic and uncontrolled change.

                                                                                                                                                                                                                  但是“冻结签字”评论暗示了几点:

                                                                                                                                                                                                                  But several points are implied by the "frozen sign off" comment:

                                                                                                                                                                                                                  • 在迭代开发和 UP 中,可以理解的是,无论对需求规范进行了多少尽职调查,一些变化都是不可避免的,并且应该是可以接受的。这种变化可能是系统的最新机会主义改进,为其所有者提供了竞争优势,也可能是由于洞察力的提高而引起的变化。

                                                                                                                                                                                                                  • In iterative development and the UP it is understood that no matter how much due diligence is given to requirements specification, some change is inevitable, and should be acceptable. This change could be a late-breaking opportunistic improvement in the system that gives its owners a competitive advantage, or change due to improved insight.

                                                                                                                                                                                                                  • 在迭代开发中,利益相关者持续参与以评估、提供反馈并按照他们真正想要的方式指导项目是一个核心价值。通过签署一组冻结的要求并等待成品来“洗手”对利益相关者的专注参与没有好处,因为他们很少能得到他们真正需要的东西。

                                                                                                                                                                                                                  • In iterative development, it is a core value to have continual engagement by the stakeholders to evaluate, provide feedback, and steer the project as they really want it. It does not benefit stakeholders to "wash their hands" of attentive engagement by signing off on a frozen set of requirements and waiting for the finished product, because they will seldom get what they really needed.

                                                                                                                                                                                                                  建设

                                                                                                                                                                                                                  Construction

                                                                                                                                                                                                                  通过构造,主要要求,无论是功能还是其他方面,都应该稳定下来,而不是最终确定,而是确定为轻微的扰动。因此,补充规范和愿景在现阶段不太可能发生太大变化。

                                                                                                                                                                                                                  By construction, the major requirementsboth functional and otherwiseshould be stabilizednot finalized, but settled down to minor perturbation. Therefore, the Supplementary Specification and Vision are unlikely to experience much change in this phase.

                                                                                                                                                                                                                    7.13. 推荐资源

                                                                                                                                                                                                                    7.13. Recommended Resources

                                                                                                                                                                                                                    大多数关于软件体系结构的书籍都包括对应用程序质量属性的需求分析的讨论,因为这些质量要求往往会强烈影响体系结构设计。一个例子是 Software Architecture in Practice [BCK98]。

                                                                                                                                                                                                                    Most books on software architecture include discussion of requirements analysis for quality attributes of the application, since these quality requirements tend to strongly influence architectural design. One example is Software Architecture in Practice [BCK98].

                                                                                                                                                                                                                    业务规则在 The Business Rule Book [Ross97] 中得到了详尽的处理。这本书提出了一个广泛、深入和透彻考虑的业务规则理论,但该方法与其他现代需求技术(如用例)或迭代开发没有很好的联系。

                                                                                                                                                                                                                    Business rules get an exhaustive treatment in The Business Rule Book [Ross97]. The book presents a broad, deep, and thoroughly-considered theory of business rules, but the method is not well-connected to other modern requirements techniques such as use cases, or to iterative development.

                                                                                                                                                                                                                    在 UP 中,愿景和补充规范工作是一项需求学科活动,可以在需求研讨会期间与用例分析一起启动。举办研讨会的一个很好的指南是 Ellen Gottesdiener 的 Requirements by Collaboration: Workshops for Defining Needs

                                                                                                                                                                                                                    In the UP, Vision and Supplementary Specification work is a requirements discipline activity that could be initiated during a requirements workshop, along with use case analysis. A good guide for running a workshop is Requirements by Collaboration: Workshops for Defining Needs by Ellen Gottesdiener.

                                                                                                                                                                                                                    RUP 联机产品包含本章中讨论的工件的模板。

                                                                                                                                                                                                                    The RUP online product contains templates for the artifacts discussed in this chapter.

                                                                                                                                                                                                                    在 Web 上,规范模板可从许多来源获得,例如 readyset.tigris.org 上的 ReadySET 模板。

                                                                                                                                                                                                                    On the Web, templates for specifications are available from many sources, such as the ReadySET templates at readyset.tigris.org.

                                                                                                                                                                                                                      第 8 章.迭代 1 基础知识

                                                                                                                                                                                                                      Chapter 8. Iteration 1Basics

                                                                                                                                                                                                                      坚硬而僵硬的断裂。柔顺占上风。

                                                                                                                                                                                                                      陶特经

                                                                                                                                                                                                                      The hard and stiff breaks. The supple prevails.

                                                                                                                                                                                                                      Tao Te Ching

                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                      • 定义细化阶段的第一次迭代。

                                                                                                                                                                                                                      • Define the first iteration in the elaboration phase.

                                                                                                                                                                                                                      • 请学习本节中的以下章节。

                                                                                                                                                                                                                      • Motivate the following chapters in this section.

                                                                                                                                                                                                                      • 描述关键的开始和细化阶段概念。

                                                                                                                                                                                                                      • Describe key inception and elaboration phase concepts.



                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                        本章总结了案例研究的 Iteration-1 要求,然后简要讨论了开始和细化阶段的流程思想。阅读所选要求对于理解以下章节中针对此迭代要解决的内容非常重要;阅读其余部分取决于您对迭代过程问题的需求或兴趣。

                                                                                                                                                                                                                        This chapter summarizes the iteration-1 requirements of the case studies, and then briefly discusses the process ideas of the inception and elaboration phases. Reading the chosen requirements is important to understand what's being tackled in the following chapters for this iteration; reading the remainder depends on your need or interest in iterative process issues.

                                                                                                                                                                                                                          8.1. 迭代 1 要求和重点:核心 OOA/D 技能

                                                                                                                                                                                                                          8.1. Iteration 1 Requirements and Emphasis: Core OOA/D Skills

                                                                                                                                                                                                                          在这些案例研究中,细化阶段的迭代 1 强调了构建对象系统中使用的一系列基本和常见的 OOA/D 技能。构建软件当然需要许多其他技能和步骤,例如数据库设计、可用性工程和 UI 设计,但在重点介绍 OOA/D 和应用 UML 的介绍中,它们不在介绍范围内。

                                                                                                                                                                                                                          In these case studies, iteration-1 of the elaboration phase emphasizes a range of fundamental and common OOA/D skills used in building object systems. Many other skills and stepssuch as database design, usability engineering, and UI designare of course needed to build software, but they are out of scope in this introduction focusing on OOA/D and applying the UML.

                                                                                                                                                                                                                          书籍迭代与真实项目迭代

                                                                                                                                                                                                                          Book Iterations vs. Real Project Iterations

                                                                                                                                                                                                                          本书中案例研究的迭代 1 是由学习目标而不是真正的项目目标驱动的。因此,迭代 1 不是以架构为中心或风险驱动的。在 UP 项目中,我们会先解决困难、有风险的事情。但是,在一本帮助人们学习基本 OOA/D 和 UML 的书的上下文中,我们希望从更简单的主题开始。

                                                                                                                                                                                                                          Iteration-1 of the case studies in this book is driven by learning goals rather than true project goals. Therefore, iteration-1 is not architecture-centric or risk-driven. On a UP project, we would tackle difficult, risky things first. But in the context of a book helping people learn fundamental OOA/D and UML, we want to start with easier topics.



                                                                                                                                                                                                                          下一代 POS

                                                                                                                                                                                                                          NextGen POS

                                                                                                                                                                                                                          NextGen POS 应用程序第一次迭代的要求如下:

                                                                                                                                                                                                                          The requirements for the first iteration of the NextGen POS application follow:

                                                                                                                                                                                                                          • 实施 Process Sale 用例的基本关键场景:输入项目并接收现金付款。

                                                                                                                                                                                                                          • Implement a basic, key scenario of the Process Sale use case: entering items and receiving a cash payment.

                                                                                                                                                                                                                          • 根据需要实施 Start Up 用例,以支持迭代的初始化需求。

                                                                                                                                                                                                                          • Implement a Start Up use case as necessary to support the initialization needs of the iteration.

                                                                                                                                                                                                                          • 没有处理任何花哨或复杂的内容,只是一个简单的快乐路径场景,以及支持它的设计和实现。

                                                                                                                                                                                                                          • Nothing fancy or complex is handled, just a simple happy path scenario, and the design and implementation to support it.

                                                                                                                                                                                                                          • 不与外部服务(例如税收计算器或产品数据库)合作。

                                                                                                                                                                                                                          • There is no collaboration with external services, such as a tax calculator or product database.

                                                                                                                                                                                                                          • 不应用复杂的定价规则。

                                                                                                                                                                                                                          • No complex pricing rules are applied.

                                                                                                                                                                                                                          支持的 UI、数据库等的设计和实现也将完成,但未详细介绍。

                                                                                                                                                                                                                          The design and implementation of the supporting UI, database, and so forth, would also be done, but is not covered in any detail.

                                                                                                                                                                                                                          垄断

                                                                                                                                                                                                                          Monopoly

                                                                                                                                                                                                                          Monopoly 应用程序第一次迭代的要求如下:

                                                                                                                                                                                                                          The requirements for the first iteration of the Monopoly application follow:

                                                                                                                                                                                                                          • 实现 Play Monopoly Game 用例的基本关键场景:玩家在棋盘的方格中移动。

                                                                                                                                                                                                                          • Implement a basic, key scenario of the Play Monopoly Game use case: players moving around the squares of the board.

                                                                                                                                                                                                                          • 根据需要实施 Start Up 用例,以支持迭代的初始化需求。

                                                                                                                                                                                                                          • Implement a Start Up use case as necessary to support the initialization needs of the iteration.

                                                                                                                                                                                                                          • 2 到 8 名玩家可以玩。

                                                                                                                                                                                                                          • Two to eight players can play.

                                                                                                                                                                                                                          • 游戏以一系列回合的形式进行。在一轮中,每个玩家轮流一次。在每一回合中,玩家将他的棋子在棋盘上顺时针前进一个方格数,这些方格数等于两个六面骰子上掷出的数字之和。

                                                                                                                                                                                                                          • A game is played as a series of rounds. During a round, each player takes one turn. In each turn, a player advances his piece clockwise around the board a number of squares equal to the sum of the number rolled on two six-sided dice.

                                                                                                                                                                                                                          • 玩游戏只需 20 轮。

                                                                                                                                                                                                                          • Play the game for only 20 rounds.

                                                                                                                                                                                                                          • 掷骰子后,将显示玩家的姓名和掷骰子。当玩家移动并落在某个方格上时,将显示该玩家的姓名和该玩家落在的方格的名称。

                                                                                                                                                                                                                          • After the dice are rolled, the name of the player and the roll are displayed. When the player moves and lands on a square, the name of the player and the name of the square that the player landed on are displayed.

                                                                                                                                                                                                                          • 在迭代 1 中,没有钱,没有赢家或输家,没有要购买或租用的财产,也没有任何类型的特殊方块。

                                                                                                                                                                                                                          • In iteration-1 there is no money, no winner or loser, no properties to buy or rent to pay, and no special squares of any kind.

                                                                                                                                                                                                                          • 每个方块都有一个名称。每个玩家都从位于名为 “Go” 的方格上的棋子开始游戏。方块名称将是 Go、Square 1、Square 2 ...方格 39

                                                                                                                                                                                                                          • Each square has a name. Every player begins the game with their piece located on the square named "Go." The square names will be Go, Square 1, Square 2, … Square 39

                                                                                                                                                                                                                          • 将游戏作为模拟运行,除了玩家数量外,不需要用户输入。

                                                                                                                                                                                                                            后续迭代将在这些基础上增长。

                                                                                                                                                                                                                          • Run the game as a simulation requiring no user input, other than the number of players.

                                                                                                                                                                                                                            Subsequent iterations will grow on these foundations.

                                                                                                                                                                                                                          在迭代开发中,我们不会一次实现所有需求

                                                                                                                                                                                                                          In Iterative Development We Don't Implement All the Requirements at Once

                                                                                                                                                                                                                          请注意,迭代 1 的这些要求是完整要求或用例的子集。例如,NextGen POS 迭代 1 要求是完整流程销售用例的简化版本;他们描述了一个简单的仅限现金的场景。

                                                                                                                                                                                                                          Note that these requirements for iteration-1 are subsets of the complete requirements or use cases. For example, the NextGen POS iteration-1 requirements are a simplified version of the complete Process Sale use case; they describe one simple cash-only scenario.

                                                                                                                                                                                                                          另请注意,我们尚未对 NextGen POS 系统进行所有需求分析,我们只详细分析了流程销售用例;许多其他尚未分析。

                                                                                                                                                                                                                          Note also that we haven't done all the requirements analysis for the NextGen POS system, we've only analyzed the Process Sale use case in detail; many others are not yet analyzed.

                                                                                                                                                                                                                          这是迭代生命周期方法(比如 UP、XP、Scrum 等)的关键理解:我们开始对需求子集进行生产质量的编程和测试,并在所有需求分析完成之前开始开发,这与瀑布流程相反。

                                                                                                                                                                                                                          This is a key understanding in iterative lifecycle methods (such as the UP, XP, Scrum, and so forth): We start production-quality programming and testing for a subset of the requirements, and we start that development before all the requirements analysis is completein contrast to a waterfall process.

                                                                                                                                                                                                                          跨迭代对同一用例进行增量开发

                                                                                                                                                                                                                          Incremental Development for the Same Use Case Across Iterations

                                                                                                                                                                                                                          请注意,并非 Process Sale 用例中的所有要求都在迭代 1 中实现。通常,在多次迭代中处理同一用例的不同场景,并逐渐扩展系统以最终处理所需的所有功能(参见图 8.1)。另一方面,简短的用例可以在一次迭代中完成。

                                                                                                                                                                                                                          Notice that not all requirements in the Process Sale use case are being implemented in iteration-1. It is common to work on varying scenarios of the same use case over several iterations and gradually extend the system to ultimately handle all the functionality required (see Figure 8.1). On the other hand, short, simple use cases may be completed within one iteration.

                                                                                                                                                                                                                          图 8.1.用例实现可能分布在多个迭代中。



                                                                                                                                                                                                                            8.2. 流程:开始和阐述

                                                                                                                                                                                                                            8.2. Process: Inception and Elaboration

                                                                                                                                                                                                                            在 UP 术语和我们的案例研究中,想象一下我们已经完成了启动阶段并正在进入细化阶段。

                                                                                                                                                                                                                            In UP terms and our case studies, imagine we have finished the inception phase and are entering the elaboration phase.

                                                                                                                                                                                                                            盗梦空间中发生了什么?

                                                                                                                                                                                                                            What Happened in Inception?

                                                                                                                                                                                                                            案例研究的开始阶段可能只持续一周。因为这不是项目的需求阶段,所以创建的工件应该简短且不完整,阶段快速,并且调查较少。

                                                                                                                                                                                                                            The inception phase of the case studies may last only one week. Because this is not the requirements phase of the project, the artifacts created should be brief and incomplete, the phase quick, and the investigation light.

                                                                                                                                                                                                                            Inception 是阐述的一小步。它确定基本的可行性、风险和范围,以决定该项目是否值得进行更认真的调查。并非所有在开始时可能合理发生的活动都已涵盖在内;这种探索强调面向需求的工件。初始阶段的一些可能活动和项目包括:

                                                                                                                                                                                                                            Inception is a short step to elaboration. It determines basic feasibility, risk, and scope, to decide if the project is worth more serious investigation. Not all activities that could reasonably occur in inception have been covered; this exploration emphasizes requirements-oriented artifacts. Some likely activities and artifacts in inception include:

                                                                                                                                                                                                                            • 简短的需求研讨会

                                                                                                                                                                                                                            • a short requirements workshop

                                                                                                                                                                                                                            • 命名的大多数参与者、目标和用例

                                                                                                                                                                                                                            • most actors, goals, and use cases named

                                                                                                                                                                                                                            • 大多数用例以简短格式编写;1020% 的用例以完整的细节编写,以提高对范围和复杂性的理解

                                                                                                                                                                                                                            • most use cases written in brief format; 1020% of the use cases are written in fully dressed detail to improve understanding of the scope and complexity

                                                                                                                                                                                                                            • 确定最具影响力和风险的质量要求

                                                                                                                                                                                                                            • most influential and risky quality requirements identified

                                                                                                                                                                                                                            • 愿景和补充规范的第一版

                                                                                                                                                                                                                            • version one of the Vision and Supplementary Specification written

                                                                                                                                                                                                                            • 风险列表

                                                                                                                                                                                                                              • 例如,领导层真的希望在 18 个月后的汉堡 POSWorld 贸易展上进行演示。但是,在更深入的调查之前,甚至还不能粗略估计演示的工作量。

                                                                                                                                                                                                                            • risk list

                                                                                                                                                                                                                              • For example, leadership really wants a demo at the POSWorld trade show in Hamburg, in 18 months. But the effort for a demo cannot yet be even roughly estimated until deeper investigation.

                                                                                                                                                                                                                            • 技术概念验证原型和其他调查,以探索特殊需求的技术可行性(“Java Swing 在触摸屏显示器上正常工作吗?

                                                                                                                                                                                                                            • technical proof-of-concept prototypes and other investigations to explore the technical feasibility of special requirements ("Does Java Swing work properly on touch-screen displays?")

                                                                                                                                                                                                                            • 面向用户界面的原型,用于阐明功能需求的愿景

                                                                                                                                                                                                                            • user interface-oriented prototypes to clarify the vision of functional requirements

                                                                                                                                                                                                                            • 关于购买/构建/重用哪些组件的建议,在细化中进行完善

                                                                                                                                                                                                                              • 例如,购买税款计算包的建议。

                                                                                                                                                                                                                            • recommendations on what components to buy/build/reuse, to be refined in elaboration

                                                                                                                                                                                                                              • For example, a recommendation to buy a tax calculation package.

                                                                                                                                                                                                                            • 提出的高级别候选架构和组件

                                                                                                                                                                                                                              • 这不是详细的架构描述,也不是最终的或正确的。相反,它是简短的推测,用作阐述调查的起点。例如,“A Java client-side application, no application server, Oracle for the database, ...”在阐述中,它可能被证明是有价值的,或者被发现是一个糟糕的想法而被拒绝。

                                                                                                                                                                                                                            • high-level candidate architecture and components proposed

                                                                                                                                                                                                                              • This is not a detailed architectural description, and it is not meant to be final or correct. Rather, it is brief speculation to use as a starting point of investigation in elaboration. For example, "A Java client-side application, no application server, Oracle for the database, …" In elaboration, it may be proven worthy, or discovered to be a poor idea and rejected.

                                                                                                                                                                                                                            • 规划第一次迭代

                                                                                                                                                                                                                            • plan for the first iteration

                                                                                                                                                                                                                            • 候选工具列表

                                                                                                                                                                                                                            • candidate tools list

                                                                                                                                                                                                                            继续阐述

                                                                                                                                                                                                                            On to Elaboration

                                                                                                                                                                                                                            细化是初始的一系列迭代,在此期间,在正常项目中:

                                                                                                                                                                                                                            Elaboration is the initial series of iterations during which, on a normal project:

                                                                                                                                                                                                                            • 核心、有风险的软件架构经过编程和测试

                                                                                                                                                                                                                            • the core, risky software architecture is programmed and tested

                                                                                                                                                                                                                            • 大多数需求被发现并稳定下来

                                                                                                                                                                                                                            • the majority of requirements are discovered and stabilized

                                                                                                                                                                                                                            • 主要风险已缓解或已停用

                                                                                                                                                                                                                            • the major risks are mitigated or retired

                                                                                                                                                                                                                            细化是团队进行认真调查、实施(程序和测试)核心架构、阐明大多数需求并解决高风险问题的初始系列迭代。在 UP 中,“风险”包括业务价值。因此,早期工作可能包括实现被认为重要但技术风险不大的方案。

                                                                                                                                                                                                                            Elaboration is the initial series of iterations during which the team does serious investigation, implements (programs and tests) the core architecture, clarifies most requirements, and tackles the high-risk issues. In the UP, "risk" includes business value. Therefore, early work may include implementing scenarios that are deemed important, but are not especially technically risky.

                                                                                                                                                                                                                            细化通常由两个或多个迭代组成;建议每次迭代在 2 到 6 周之间;除非团队规模庞大,否则更喜欢较短的版本。每次迭代都有时间限制,这意味着其结束日期是固定的。

                                                                                                                                                                                                                            Elaboration often consists of two or more iterations; each iteration is recommended to be between two and six weeks; prefer the shorter versions unless the team size is massive. Each iteration is timeboxed, meaning its end date is fixed.

                                                                                                                                                                                                                            细化不是一个设计阶段,也不是一个阶段,也不是模型完全开发以准备在构建步骤中实施的阶段,这将是将瀑布式思想叠加在迭代开发和 UP 上的一个例子。

                                                                                                                                                                                                                            Elaboration is not a design phase or a phase when the models are fully developed in preparation for implementation in the construction stepthat would be an example of superimposing waterfall ideas on iterative development and the UP.

                                                                                                                                                                                                                            在此阶段,不是创建一次性原型;相反,代码和设计是最终系统的生产质量部分。在一些 UP 描述中,可能被误解的术语“架构原型”被用来描述部分系统。这并不意味着要成为可丢弃实验意义上的原型;在 UP 中,它表示最终系统的生产子集。更常见的是,它被称为可执行体系结构体系结构基线

                                                                                                                                                                                                                            During this phase, one is not creating throw-away prototypes; rather, the code and design are production-quality portions of the final system. In some UP descriptions, the potentially misunderstood term "architectural prototype" is used to describe the partial system. This is not meant to be a prototype in the sense of a discardable experiment; in the UP, it means a production subset of the final system. More commonly it is called the executable architecture or architectural baseline.

                                                                                                                                                                                                                            一句话详细说明:

                                                                                                                                                                                                                            Elaboration in one sentence:

                                                                                                                                                                                                                            构建核心架构,解决高风险元素,定义大多数需求,并估计整体进度和资源。

                                                                                                                                                                                                                            Build the core architecture, resolve the high-risk elements, define most requirements, and estimate the overall schedule and resources.



                                                                                                                                                                                                                            一些关键思想和最佳实践将体现在阐述中:

                                                                                                                                                                                                                            Some key ideas and best practices will manifest in elaboration:

                                                                                                                                                                                                                            • 执行短时间限制的风险驱动迭代

                                                                                                                                                                                                                            • do short timeboxed risk-driven iterations

                                                                                                                                                                                                                            • 尽早开始编程

                                                                                                                                                                                                                            • start programming early

                                                                                                                                                                                                                            • 自适应地设计、实施和测试架构的核心和风险部分

                                                                                                                                                                                                                            • adaptively design, implement, and test the core and risky parts of the architecture

                                                                                                                                                                                                                            • 尽早、经常、现实地进行测试

                                                                                                                                                                                                                            • test early, often, realistically

                                                                                                                                                                                                                            • 根据测试、用户和开发人员的反馈进行调整

                                                                                                                                                                                                                            • adapt based on feedback from tests, users, developers

                                                                                                                                                                                                                            • 通过一系列研讨会详细编写大多数用例和其他需求,每次细化迭代一次

                                                                                                                                                                                                                            • write most of the use cases and other requirements in detail, through a series of workshops, once per elaboration iteration

                                                                                                                                                                                                                            哪些工件可能从细化开始?

                                                                                                                                                                                                                            Table 8.1 列出了可能在细化中开始的示例工件,并指出了它们解决的问题。后续章节将更详细地研究其中的一些,尤其是 Domain Model 和 Design Model。为简洁起见,该表排除了可能在 inception 中开始的工件;它引入了更有可能从 Elaboration 开始的工件。请注意,这些不会在一次迭代中完成;相反,它们将通过一系列迭代进行优化。

                                                                                                                                                                                                                            Table 8.1 lists sample artifacts that may be started in elaboration, and indicates the issues they address. Subsequent chapters will examine some of these in greater detail, especially the Domain Model and Design Model. For brevity, the table excludes artifacts that may have begun in inception; it introduces artifacts that are more likely to start in elaboration. Note these will not be completed in one iteration; rather, they will be refined over a series of iterations.

                                                                                                                                                                                                                            表 8.1.样本细化工件,不包括那些在开始时开始的工件。

                                                                                                                                                                                                                            人工制品

                                                                                                                                                                                                                            Artifact

                                                                                                                                                                                                                            评论

                                                                                                                                                                                                                            Comment

                                                                                                                                                                                                                            域模型

                                                                                                                                                                                                                            Domain Model

                                                                                                                                                                                                                            这是域概念的可视化;它类似于域实体的静态信息模型。

                                                                                                                                                                                                                            This is a visualization of the domain concepts; it is similar to a static information model of the domain entities.

                                                                                                                                                                                                                            设计模型

                                                                                                                                                                                                                            Design Model

                                                                                                                                                                                                                            这是描述逻辑设计的一组图。这包括软件类图、对象交互图、包图等。

                                                                                                                                                                                                                            This is the set of diagrams that describes the logical design. This includes software class diagrams, object interaction diagrams, package diagrams, and so forth.

                                                                                                                                                                                                                            软件架构文档

                                                                                                                                                                                                                            Software Architecture Document

                                                                                                                                                                                                                            一种学习辅助工具,用于总结设计中的关键体系结构问题及其解决方法。它是对杰出设计理念及其在系统中的动机的总结。

                                                                                                                                                                                                                            A learning aid that summarizes the key architectural issues and their resolution in the design. It is a summary of the outstanding design ideas and their motivation in the system.

                                                                                                                                                                                                                            数据模型

                                                                                                                                                                                                                            Data Model

                                                                                                                                                                                                                            这包括数据库架构以及对象和非对象表示之间的映射策略。

                                                                                                                                                                                                                            This includes the database schemas, and the mapping strategies between object and non-object representations.

                                                                                                                                                                                                                            用例 Storyboard、UI 原型

                                                                                                                                                                                                                            Use-Case Storyboards, UI Prototypes

                                                                                                                                                                                                                            用户界面、导航路径、可用性模型等的描述。

                                                                                                                                                                                                                            A description of the user interface, paths of navigation, usability models, and so forth.



                                                                                                                                                                                                                            你知道你不懂 Eruation 的时候......
                                                                                                                                                                                                                            • 对于大多数项目来说,它不仅仅是 “几个” 月。

                                                                                                                                                                                                                            • It is more than "a few" months long for most projects.

                                                                                                                                                                                                                            • 它只有一次迭代(对于易于理解的问题,极少数例外)。

                                                                                                                                                                                                                            • It only has one iteration (with rare exceptions for well-understood problems).

                                                                                                                                                                                                                            • 大多数要求在制定之前就已经确定了。

                                                                                                                                                                                                                            • Most requirements were defined before elaboration.

                                                                                                                                                                                                                            • 风险元素和核心架构没有得到解决。

                                                                                                                                                                                                                            • The risky elements and core architecture are not being tackled.

                                                                                                                                                                                                                            • 它不会产生可执行的体系结构;没有生产代码编程。

                                                                                                                                                                                                                            • It does not result in an executable architecture; there is no production-code programming.

                                                                                                                                                                                                                            • 它主要被视为需求或设计阶段,在施工的实施阶段之前。

                                                                                                                                                                                                                            • It is considered primarily a requirements or design phase, preceding an implementation phase in construction.

                                                                                                                                                                                                                            • 在编程之前,会尝试进行全面而仔细的设计。

                                                                                                                                                                                                                            • There is an attempt to do a full and careful design before programming.

                                                                                                                                                                                                                            • 反馈和适应最少;用户不会持续参与评估和反馈。

                                                                                                                                                                                                                            • There is minimal feedback and adaptation; users are not continually engaged in evaluation and feedback.

                                                                                                                                                                                                                            • 没有早期和现实的测试。

                                                                                                                                                                                                                            • There is no early and realistic testing.

                                                                                                                                                                                                                            • 体系结构在编程之前推测性地最终确定。

                                                                                                                                                                                                                            • The architecture is speculatively finalized before programming.

                                                                                                                                                                                                                            • 它被认为是进行概念验证编程的一个步骤,而不是对生产核心可执行架构进行编程。

                                                                                                                                                                                                                            • It is considered a step to do the proof-of-concept programming, rather than programming the production core executable architecture.

                                                                                                                                                                                                                            如果一个项目表现出这些症状,则说明阐述阶段没有被理解,瀑布式思维已经叠加在 UP 上。

                                                                                                                                                                                                                            If a project exhibits these symptoms, the elaboration phase was not understood, and waterfall-thinking has been superimposed on the UP.

                                                                                                                                                                                                                              8.3. 流程:规划下一次迭代

                                                                                                                                                                                                                              8.3. Process: Planning the Next Iteration

                                                                                                                                                                                                                              规划和项目管理是重要但宏大的话题。这里简要介绍了一些想法,从第 673 页开始还有更多提示。

                                                                                                                                                                                                                              Planning and project management are important but large topics. A few ideas are briefly presented here, and there are some more tips starting on p. 673.

                                                                                                                                                                                                                              按风险、覆盖范围和关键性组织需求和迭代。

                                                                                                                                                                                                                              Organize requirements and iterations by risk, coverage, and criticality.

                                                                                                                                                                                                                              • 风险包括技术复杂性和其他因素,例如工作量或可用性的不确定性。

                                                                                                                                                                                                                              • Risk includes both technical complexity and other factors, such as uncertainty of effort or usability.

                                                                                                                                                                                                                              • 覆盖率意味着系统的所有主要部分至少在早期迭代中被触及,也许是跨许多组件的“宽而浅”的实现。

                                                                                                                                                                                                                              • Coverage implies that all major parts of the system are at least touched on in early iterationsperhaps a "wide and shallow" implementation across many components.

                                                                                                                                                                                                                              • 关键性是指客户认为具有高业务价值的功能。

                                                                                                                                                                                                                              • Criticality refers to functions the client considers of high business value.

                                                                                                                                                                                                                              这些标准用于对迭代中的工作进行排名。用例或用例场景对实施进行排名:早期迭代实施排名靠前的场景。此外,某些要求表示为与特定使用案例无关的高级功能,例如日志记录服务。这些也被排序。

                                                                                                                                                                                                                              These criteria are used to rank work across iterations. Use cases or use case scenarios are ranked for implementationearly iterations implement high ranking scenarios. In addition, some requirements are expressed as high-level features unrelated to a particular use case, such as a logging service. These are also ranked.

                                                                                                                                                                                                                              排名在迭代 1 之前完成,但在迭代 2 之前再次进行,依此类推,因为新需求和新洞察会影响顺序。也就是说,迭代计划是自适应的,而不是在项目开始时推测性地冻结。通常基于一些协作排名技术,会出现一组需求。例如:

                                                                                                                                                                                                                              The ranking is done before iteration-1, but then again before iteration-2, and so forth, as new requirements and new insights influence the order. That is, the plan of iterations is adaptive, rather than speculatively frozen at the beginning of the project. Usually based on some collaborative ranking technique, a grouping of requirements will emerge. For example:

                                                                                                                                                                                                                              Rank

                                                                                                                                                                                                                              要求 (用例或功能)

                                                                                                                                                                                                                              Requirement (Use Case or Feature)

                                                                                                                                                                                                                              评论

                                                                                                                                                                                                                              Comment

                                                                                                                                                                                                                              High

                                                                                                                                                                                                                              流程销售

                                                                                                                                                                                                                              Process Sale

                                                                                                                                                                                                                              伐木

                                                                                                                                                                                                                              Logging

                                                                                                                                                                                                                              在所有排名中得分均很高。

                                                                                                                                                                                                                              Scores high on all rankings.

                                                                                                                                                                                                                              普遍。很难在晚些时候添加。

                                                                                                                                                                                                                              Pervasive. Hard to add late.

                                                                                                                                                                                                                              中等

                                                                                                                                                                                                                              Medium

                                                                                                                                                                                                                              维护用户

                                                                                                                                                                                                                              Maintain Users

                                                                                                                                                                                                                              影响 security 子域。

                                                                                                                                                                                                                              Affects security subdomain.

                                                                                                                                                                                                                              Low



                                                                                                                                                                                                                              根据此排名,我们看到 Process Sale 用例的一些关键架构重要场景应该在早期迭代中得到解决。此列表并不详尽;其他要求也将得到解决。此外,将在每次迭代中处理隐式或显式的 Start Up 用例,以满足其初始化需求。

                                                                                                                                                                                                                              Based on this ranking, we see that some key architecturally significant scenarios of the Process Sale use case should be tackled in early iterations. This list is not exhaustive; other requirements will also be tackled. In addition, an implicit or explicit Start Up use case will be worked on in each iteration, to meet its initialization needs.

                                                                                                                                                                                                                                第 9 章.域模型

                                                                                                                                                                                                                                Chapter 9. Domain Models

                                                                                                                                                                                                                                这在实践中一切都很好,但在理论上永远不会奏效。

                                                                                                                                                                                                                                匿名管理格言

                                                                                                                                                                                                                                It's all very well in practice, but it will never work in theory.

                                                                                                                                                                                                                                anonymous management maxim

                                                                                                                                                                                                                                目标

                                                                                                                                                                                                                                Objectives

                                                                                                                                                                                                                                • 标识与当前迭代相关的概念类。

                                                                                                                                                                                                                                • Identify conceptual classes related to the current iteration.

                                                                                                                                                                                                                                • 创建初始域模型。

                                                                                                                                                                                                                                • Create an initial domain model.

                                                                                                                                                                                                                                • 对适当的属性和关联进行建模。

                                                                                                                                                                                                                                • Model appropriate attributes and associations.



                                                                                                                                                                                                                                  介绍

                                                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                                                  域模型是 OO 分析中最重要和最经典的模型。[1] 它说明了域中值得注意的概念。它可以作为设计某些软件对象的灵感来源,并将成为案例研究中探索的几个工件的输入。本章还展示了 OOA/D 知识相对于 UML 表示法的价值;基本符号很简单,但有用的 ModelExpertise 需要数周或数月的微妙建模指南。本章探讨了创建域模型的基本技能。

                                                                                                                                                                                                                                  A domain model is the most importantand classicmodel in OO analysis.[1] It illustrates noteworthy concepts in a domain. It can act as a source of inspiration for designing some software objects and will be an input to several artifacts explored in the case studies. This chapter also shows the value of OOA/D knowledge over UML notation; the basic notation is trivial, but there are subtle modeling guidelines for a useful modelexpertise can take weeks or months. This chapter explores basic skills in creating domain models.

                                                                                                                                                                                                                                  [1] 用例是一个重要的需求分析工件,但不是面向对象的。它们强调活动视图。

                                                                                                                                                                                                                                  [1] Use cases are an important requirements analysis artifact, but are not object-oriented. They emphasize an activity view.



                                                                                                                                                                                                                                  与敏捷建模和 UP 精神中的所有事物一样,领域模型是可选的。强调领域模型的 UP 工件影响如图 9.1 所示。当前迭代正在开发的用例场景的约束,域模型可以发展为显示相关的值得注意的概念。相关的用例概念和专家的见解将输入到其创建中。该模型反过来可以影响操作合约、词汇表和 Design Model,尤其是 Design Model 的域层中的软件对象。

                                                                                                                                                                                                                                  As with all things in an agile modeling and UP spirit, a domain model is optional. UP artifact influence emphasizing a domain model is shown in Figure 9.1. Bounded by the use case scenarios under development for the current iteration, the domain model can be evolved to show related noteworthy concepts. The related use case concepts and insight of experts will be input to its creation. The model can in turn influence operation contracts, a glossary, and the Design Model, especially the software objects in the domain layer of the Design Model.

                                                                                                                                                                                                                                  图 9.1.示例 UP 伪影影响。





                                                                                                                                                                                                                                    9.1. 示例

                                                                                                                                                                                                                                    9.1. Example

                                                                                                                                                                                                                                    图 9.2 显示了使用 UML 类图表示法绘制的部分域模型。它说明了 PaymentSale 的概念在这个领域中很重要,Payment 以一种有意义的方式与 Sale 相关,并且 Sale 有日期和时间,我们关心的信息属性。

                                                                                                                                                                                                                                    Figure 9.2 shows a partial domain model drawn with UML class diagram notation. It illustrates that the conceptual classes of Payment and Sale are significant in this domain, that a Payment is related to a Sale in a way that is meaningful to note, and that a Sale has a date and time, information attributes we care about.

                                                                                                                                                                                                                                    图 9.2.Partial domain modela visual dictionary.



                                                                                                                                                                                                                                    将 UML 类图表示法应用于域模型将生成概念透视模型。

                                                                                                                                                                                                                                    Applying the UML class diagram notation for a domain model yields a conceptual perspective model.



                                                                                                                                                                                                                                    确定一组丰富的概念类是 OO 分析的核心。如果它是通过技能和短时间投入完成的(比如,每个早期迭代不超过几个小时),它通常会在设计过程中得到回报,因为它支持更好的理解和沟通。

                                                                                                                                                                                                                                    Identifying a rich set of conceptual classes is at the heart of OO analysis. If it is done with skill and short time investment (say, no more than a few hours in each early iteration), it usually pays off during design, when it supports better understanding and communication.

                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                    避免瀑布式的大建模工作来制作一个彻底或 “正确” 的领域模型,这也永远不会,而且这种过度建模工作会导致分析瘫痪,投资回报很少或没有。

                                                                                                                                                                                                                                    Avoid a waterfall-mindset big-modeling effort to make a thorough or "correct" domain modelit won't ever be either, and such over-modeling efforts lead to analysis paralysis, with little or no return on the investment.



                                                                                                                                                                                                                                      9.2. 什么是域模型?

                                                                                                                                                                                                                                      9.2. What is a Domain Model?

                                                                                                                                                                                                                                      典型的面向对象的分析步骤是将域分解为值得注意的概念或对象。

                                                                                                                                                                                                                                      The quintessential object-oriented analysis step is the decomposition of a domain into noteworthy concepts or objects.

                                                                                                                                                                                                                                      域模型是域中概念类或真实情况对象的可视化表示 [MO95Fowler96]。域模型也称为概念模型(本书第一版中使用的术语)、域对象模型和分析对象模型[2]

                                                                                                                                                                                                                                      A domain model is a visual representation of conceptual classes or real-situation objects in a domain [MO95, Fowler96]. Domain models have also been called conceptual models (the term used in the first edition of this book), domain object models, and analysis object models.[2]

                                                                                                                                                                                                                                      [2] 它们还与概念实体关系模型有关,这些模型能够显示域的纯概念视图,但已被广泛重新解释为数据库设计的数据模型。域模型不是数据模型。

                                                                                                                                                                                                                                      [2] They are also related to conceptual entity relationship models, which are capable of showing purely conceptual views of domains, but that have been widely re-interpreted as data models for database design. Domain models are not data models.

                                                                                                                                                                                                                                      定义

                                                                                                                                                                                                                                      Definition

                                                                                                                                                                                                                                      在 UP 中,术语“域模型”是指真实情况概念类的表示,而不是软件对象的表示。该术语并不意味着描述软件类、软件体系结构的域层或具有职责的软件对象的一组图表。

                                                                                                                                                                                                                                      In the UP, the term "Domain Model" means a representation of real-situation conceptual classes, not of software objects. The term does not mean a set of diagrams describing software classes, the domain layer of a software architecture, or software objects with responsibilities.



                                                                                                                                                                                                                                      UP 将 Domain Model[3] 定义为可以在业务建模学科中创建的工件之一。更准确地说,UP 领域模型是 UP 业务对象模型 (BOM) 的专业化,“专注于解释对业务领域很重要的'事物'和产品”[RUP]。也就是说,域模型侧重于一个域,例如与 POS 相关的事物。更宽泛的 BOM 在本介绍性文本中没有涉及,也不是我鼓励创建的东西(因为它可能会导致过多的前期建模),它是一个扩展的、通常非常大且难以创建的多域模型,它涵盖了整个业务及其所有子域。

                                                                                                                                                                                                                                      The UP defines the Domain Model[3] as one of the artifacts that may be created in the Business Modeling discipline. More precisely, the UP Domain Model is a specialization of the UP Business Object Model (BOM) "focusing on explaining 'things' and products important to a business domain" [RUP]. That is, a Domain Model focuses on one domain, such as POS related things. The more broad BOM, not covered in this introductory text and not something I encourage creating (because it can lead to too much up-front modeling), is an expanded, often very large and difficult to create, multi-domain model that covers the entire business and all its sub-domains.

                                                                                                                                                                                                                                      [3] “Domain Model” 或术语的大写用于强调它是 UP 中定义的官方模型名称,而不是通常众所周知的“Domain models”概念。

                                                                                                                                                                                                                                      [3] Capitalization of "Domain Model" or terms is used to emphasize it as an official model name defined in the UP, versus the general well-known concept of "domain models."

                                                                                                                                                                                                                                      应用 UML 表示法,域模型由一组类图表示,其中未定义任何操作(方法签名)。它提供了一个概念视角。它可能显示:

                                                                                                                                                                                                                                      Applying UML notation, a domain model is illustrated with a set of class diagrams in which no operations (method signatures) are defined. It provides a conceptual perspective. It may show:

                                                                                                                                                                                                                                      • 域对象或概念类

                                                                                                                                                                                                                                      • domain objects or conceptual classes

                                                                                                                                                                                                                                      • 概念类之间的关联

                                                                                                                                                                                                                                      • associations between conceptual classes

                                                                                                                                                                                                                                      • 概念类的属性

                                                                                                                                                                                                                                      • attributes of conceptual classes

                                                                                                                                                                                                                                      定义:为什么将域模型称为“视觉词典”?

                                                                                                                                                                                                                                      Definition: Why Call a Domain Model a "Visual Dictionary"?

                                                                                                                                                                                                                                      请思考一下图 9.2。了解它如何可视化和关联域中的单词或概念。它还显示了概念类的抽象,因为还有许多其他关于收银、销售等的内容可以传达。

                                                                                                                                                                                                                                      Please reflect on Figure 9.2 for a moment. See how it visualizes and relates words or concepts in the domain. It also shows an abstraction of the conceptual classes, because there are many other things one could communicate about registers, sales, and so forth.

                                                                                                                                                                                                                                      它所说明的信息(使用 UML 表示法)也可以用纯文本表示(在 UP 词汇表中)。但是很容易理解这些术语,尤其是它们在视觉语言中的关系,因为我们的大脑擅长理解视觉元素和线条连接。

                                                                                                                                                                                                                                      The information it illustrates (using UML notation) could alternatively have been expressed in plain text (in the UP Glossary). But it's easy to understand the terms and especially their relationships in a visual language, since our brains are good at understanding visual elements and line connections.

                                                                                                                                                                                                                                      因此,域模型是域值得注意的抽象、域词汇和信息内容的可视化字典

                                                                                                                                                                                                                                      Therefore, the domain model is a visual dictionary of the noteworthy abstractions, domain vocabulary, and information content of the domain.

                                                                                                                                                                                                                                      定义:域模型是软件业务对象的图片吗?

                                                                                                                                                                                                                                      Definition: Is a Domain Model a Picture of Software Business Objects?

                                                                                                                                                                                                                                      如图 9.3 所示,UP 域模型是真实情况下感兴趣域中事物的可视化,而不是软件对象(如 Java 或 C# 类)或具有职责的软件对象(见图 9.4)。因此,以下元素不适用于域模型:

                                                                                                                                                                                                                                      A UP Domain Model, as shown in Figure 9.3, is a visualization of things in a real-situation domain of interest, not of software objects such as Java or C# classes, or software objects with responsibilities (see Figure 9.4). Therefore, the following elements are not suitable in a domain model:

                                                                                                                                                                                                                                      • 软件工件,例如窗口或数据库,除非正在建模的域是软件概念,例如图形用户界面模型。

                                                                                                                                                                                                                                      • Software artifacts, such as a window or a database, unless the domain being modeled is of software concepts, such as a model of graphical user interfaces.

                                                                                                                                                                                                                                      • 职责或方法。[4]

                                                                                                                                                                                                                                        [4] 在对象建模中,我们通常谈论与软件对象相关的职责。方法纯粹是一个软件概念。但是,域模型描述的是实际情况的概念,而不是软件对象。在设计工作中考虑对象责任非常重要;它只是不是这个模型的一部分。

                                                                                                                                                                                                                                      • Responsibilities or methods.[4]

                                                                                                                                                                                                                                        [4] In object modeling, we usually speak of responsibilities related to software objects. And methods are purely a software concept. But, the domain model describes real-situation concepts, not software objects. Considering object responsibilities during design work is very important; it is just not part of this model.

                                                                                                                                                                                                                                      图 9.3.域模型显示实际情况的概念类,而不是软件类。



                                                                                                                                                                                                                                      图 9.4.域模型不显示软件工件或类。



                                                                                                                                                                                                                                      定义:“域模型”的两个传统含义是什么?

                                                                                                                                                                                                                                      Definition: What are Two Traditional Meanings of "Domain Model"?

                                                                                                                                                                                                                                      在 UP 以及本章中,“域模型”是世界真实情况中对象的概念视角,而不是软件视角。但这个词是超载的;它还被用来表示“软件对象的域层”(尤其是在 Smalltalk 社区中,我在 1980 年代完成了大部分早期的 OO 开发工作)。也就是说,表示层或 UI 层下面的软件对象层,由域对象软件对象组成,这些对象使用相关的“业务逻辑”或“域逻辑”方法表示问题域空间中的事物。例如,具有 getSquare 方法的 Board 软件类。

                                                                                                                                                                                                                                      In the UP and thus this chapter, "Domain Model" is a conceptual perspective of objects in a real situation of the world, not a software perspective. But the term is overloaded; it also has been used (especially in the Smalltalk community where I did most of my early OO development work in the 1980s) to mean "the domain layer of software objects." That is, the layer of software objects below the presentation or UI layer that is composed of domain objectssoftware objects that represent things in the problem domain space with related "business logic" or "domain logic" methods. For example, a Board software class with a getSquare method.

                                                                                                                                                                                                                                      哪个定义是正确的?嗯,他们都!该术语在不同的社区中长期以来一直被用来表示不同的事物。

                                                                                                                                                                                                                                      Which definition is correct? Well, all of them! The term has long established uses in different communities to mean different things.

                                                                                                                                                                                                                                      我见过很多人因为人们以不同的方式使用这个词而产生困惑,他们没有解释他们想要的含义,也没有意识到其他人可能会以不同的方式使用它。

                                                                                                                                                                                                                                      I've seen lots of confusion generated by people using the term in different ways, without explaining which meaning they intend, and without recognizing that others may be using it differently.

                                                                                                                                                                                                                                      在这本书中,我通常会编写 domain layer 来表示 domain model 的第二个面向软件的含义,因为这很常见。

                                                                                                                                                                                                                                      In this book, I'll usually write domain layer to indicate the second software-oriented meaning of domain model, as that's quite common.

                                                                                                                                                                                                                                      定义:什么是概念类?

                                                                                                                                                                                                                                      Definition: What are Conceptual Classes?

                                                                                                                                                                                                                                      域模型说明了域中的概念类或词汇。非正式地,概念类是一个想法、事物或对象。更正式地说,概念类可以根据其符号、内涵和外延来考虑 [MO95](见图 9.5)。

                                                                                                                                                                                                                                      The domain model illustrates conceptual classes or vocabulary in the domain. Informally, a conceptual class is an idea, thing, or object. More formally, a conceptual class may be considered in terms of its symbol, intension, and extension [MO95] (see Figure 9.5).

                                                                                                                                                                                                                                      • 表示概念类的符号单词或图像。

                                                                                                                                                                                                                                      • Symbol words or images representing a conceptual class.

                                                                                                                                                                                                                                      • Intension(意涵)概念类的定义。

                                                                                                                                                                                                                                      • Intension the definition of a conceptual class.

                                                                                                                                                                                                                                      • 扩展 概念类适用的示例集。

                                                                                                                                                                                                                                      • Extension the set of examples to which the conceptual class applies.

                                                                                                                                                                                                                                      图 9.5.概念类具有 symbol、inemphasis 和 extension。



                                                                                                                                                                                                                                      例如,考虑购买交易事件的概念类。我可以选择用(英文)符号 Sale 来命名它。Sale 的意图可以说明它 “代表购买交易的事件,并有日期和时间”。Sale 的扩展是所有 sales 的例子;换句话说,是 Universe 中所有 Sales 实例的集合。

                                                                                                                                                                                                                                      For example, consider the conceptual class for the event of a purchase transaction. I may choose to name it by the (English) symbol Sale. The intension of a Sale may state that it "represents the event of a purchase transaction, and has a date and time." The extension of Sale is all the examples of sales; in other words, the set of all sale instances in the universe.

                                                                                                                                                                                                                                      定义:域模型和数据模型是一回事吗?

                                                                                                                                                                                                                                      Definition: Are Domain and Data Models the Same Thing?

                                                                                                                                                                                                                                      域模型不是数据模型(根据定义,它显示要存储在某处的持久数据),因此不要仅仅因为需求没有表明任何明显的需要记住有关它的信息(关系数据库设计的数据建模中常见的标准,但与域建模无关)或因为概念类没有属性而排除该类。例如,具有无属性的概念类或在域中具有纯行为角色而不是信息角色的概念类是有效的。

                                                                                                                                                                                                                                      A domain model is not a data model (which by definition shows persistent data to be stored somewhere), so do not exclude a class simply because the requirements don't indicate any obvious need to remember information about it (a criterion common in data modeling for relational database design, but not relevant to domain modeling) or because the conceptual class has no attributes. For example, it's valid to have attributeless conceptual classes, or conceptual classes that have a purely behavioral role in the domain instead of an information role.

                                                                                                                                                                                                                                        9.3. 动机:为什么要创建域模型?

                                                                                                                                                                                                                                        9.3. Motivation: Why Create a Domain Model?

                                                                                                                                                                                                                                        我将分享一个我在 OO 咨询和辅导中多次经历的故事。在 1990 年代初期,我与一个小组合作,在温哥华的 Smalltalk 开发一个殡仪服务业务系统(您应该看到域模型!现在,我对这项业务几乎一无所知,因此创建领域模型的一个原因是这样我就可以开始理解他们的关键概念和词汇。

                                                                                                                                                                                                                                        I'll share a story that I've experienced many times in OO consulting and coaching. In the early 1990s I was working with a group developing a funeral services business system in Smalltalk, in Vancouver (you should see the domain model!). Now, I knew almost nothing about this business, so one reason to create a domain model was so that I could start to understand their key concepts and vocabulary.

                                                                                                                                                                                                                                        我们还希望创建一个 Smalltalk 对象的域层,该层表示业务对象和逻辑。因此,我们可能花了一个小时来草拟一个类似 UML(实际上是 OMT,其表示法启发了 UML)的领域模型,不关心软件,而只是简单地确定关键术语。然后,我们在领域模型中草拟的那些术语,比如 Service(比如殡仪馆里的花,或者播放“You Can't Always Get What You Want”),也被用作在 Smalltalk 中实现的领域层中的关键软件类的名称。

                                                                                                                                                                                                                                        We also wanted to create a domain layer of Smalltalk objects representing business objects and logic. So, we spent perhaps one hour sketching a UML-ish (actually OMT-ish, whose notation inspired UML) domain model, not worrying about software, but simply identifying the key terms. Then, those terms we sketched in the domain model, such as Service (like flowers in the funeral room, or playing "You Can't Always Get What You Want"), were also used as the names of key software classes in our domain layer implemented in Smalltalk.



                                                                                                                                                                                                                                        领域模型和领域层(真正的 “服务” 和 Smalltalk 服务)之间的命名相似性支持了软件表示和我们对领域的心智模型之间的较小差距。

                                                                                                                                                                                                                                        This similarity of naming between the domain model and the domain layer (a real "service" and a Smalltalk Service) supported a lower gap between the software representation and our mental model of the domain.

                                                                                                                                                                                                                                        动机:通过 OO 建模降低代表性差距

                                                                                                                                                                                                                                        Motivation: Lower Representational Gap with OO Modeling

                                                                                                                                                                                                                                        这是 OO 中的一个关键思想:在域层中使用软件类名,其灵感来自域模型中的名称,其中对象具有域熟悉的信息和职责。图 9.6 说明了这个想法。这支持了我们的心理模型和软件模型之间的低表征差距。这不仅仅是一个哲学上的美好,它对时间和金钱都有实际的影响。例如,下面是一个 1953 年编写的源代码工资单程序:

                                                                                                                                                                                                                                        This is a key idea in OO: Use software class names in the domain layer inspired from names in the domain model, with objects having domain-familiar information and responsibilities. Figure 9.6 illustrates the idea. This supports a low representational gap between our mental and software models. And that's not just a philosophical nicetyit has a practical time-and-money impact. For example, here's a source-code payroll program written in 1953:

                                                                                                                                                                                                                                        1000010101000111101010101010001010101010101111010101 …

                                                                                                                                                                                                                                        1000010101000111101010101010001010101010101111010101 …

                                                                                                                                                                                                                                        图 9.6.通过 OO 建模降低表示差距。



                                                                                                                                                                                                                                        作为计算机科学的人,我们知道它会运行,但这种软件表示与我们对薪资领域的心智模型之间的差距是巨大的;这深刻影响了对软件的理解(和修改)。OO 建模可以缩小这一差距。

                                                                                                                                                                                                                                        As computer science people, we know it runs, but the gap between this software representation and our mental model of the payroll domain is huge; that profoundly affects comprehension (and modification) of the software. OO modeling can lower that gap.

                                                                                                                                                                                                                                        当然,对象技术也很有价值,因为它可以支持设计易于扩展和扩展的优雅、松散耦合的系统,这将在本书的其余部分进行探讨。减小表示差距是有用的,但可以说是次要的,因为对象在支持易于更改和扩展以及管理和隐藏复杂性方面的优势是次要的。

                                                                                                                                                                                                                                        Of course, object technology is also of value because it can support the design of elegant, loosely coupled systems that scale and extend easily, as will be explored in the remainder of the book. A lowered representational gap is useful, but arguably secondary to the advantage objects have in supporting ease of change and extension, and managing and hiding complexity.

                                                                                                                                                                                                                                          9.4. 指南:如何创建域模型?

                                                                                                                                                                                                                                          9.4. Guideline: How to Create a Domain Model?

                                                                                                                                                                                                                                          design 下的当前迭代要求的约束:

                                                                                                                                                                                                                                          Bounded by the current iteration requirements under design:

                                                                                                                                                                                                                                          1. 查找概念类(请参阅以下指南)。

                                                                                                                                                                                                                                          2. Find the conceptual classes (see a following guideline).

                                                                                                                                                                                                                                          3. 在 UML 类图中将它们绘制为类。

                                                                                                                                                                                                                                          4. Draw them as classes in a UML class diagram.

                                                                                                                                                                                                                                          5. 添加关联属性。见第 149 页和第 158 页。

                                                                                                                                                                                                                                          6. Add associations and attributes. See p. 149 and p. 158.

                                                                                                                                                                                                                                            9.5. 指南:如何找到概念类?

                                                                                                                                                                                                                                            9.5. Guideline: How to Find Conceptual Classes?

                                                                                                                                                                                                                                            由于域模型显示概念类,因此一个中心问题是:如何找到它们?

                                                                                                                                                                                                                                            Since a domain model shows conceptual classes, a central question is: How do I find them?

                                                                                                                                                                                                                                            找到概念类的三种策略是什么?

                                                                                                                                                                                                                                            What are Three Strategies to Find Conceptual Classes?

                                                                                                                                                                                                                                            1. 重用或修改现有模型。这是第一种、最好且通常最简单的方法,如果可以的话,我将从这里开始。对于许多常见领域,例如库存、财务、健康等,都有已发布的、精心设计的域模型和数据模型(可以修改为域模型)。我将转向的示例书籍包括 Martin Fowler 的 Analysis Patterns、David Hay 的 Data Model Patterns 和 Len Silverston 的 Data Model Resource Book(第 1 卷和第 2 卷)。

                                                                                                                                                                                                                                            2. Reuse or modify existing models. This is the first, best, and usually easiest approach, and where I will start if I can. There are published, well-crafted domain models and data models (which can be modified into domain models) for many common domains, such as inventory, finance, health, and so forth. Example books that I'll turn to include Analysis Patterns by Martin Fowler, Data Model Patterns by David Hay, and the Data Model Resource Book (volumes 1 and 2) by Len Silverston.

                                                                                                                                                                                                                                            3. 使用类别列表。

                                                                                                                                                                                                                                            4. Use a category list.

                                                                                                                                                                                                                                            5. 识别名词短语。

                                                                                                                                                                                                                                            6. Identify noun phrases.

                                                                                                                                                                                                                                            重用现有模型非常好,但超出了我们的范围。第二种方法,使用类别列表,也很有用。

                                                                                                                                                                                                                                            Reusing existing models is excellent, but outside our scope. The second method, using a category list, is also useful.

                                                                                                                                                                                                                                            方法 2:使用类别列表

                                                                                                                                                                                                                                            Method 2: Use a Category List

                                                                                                                                                                                                                                            我们可以通过列出候选概念类来启动域模型的创建。表 9.1 包含许多通常值得考虑的常见类别,重点是业务信息系统需求。这些指南还建议了分析中的一些优先事项。示例来自 1) POS、2) Monopoly 和 3) 航空公司预订域。

                                                                                                                                                                                                                                            We can kick-start the creation of a domain model by making a list of candidate conceptual classes. Table 9.1 contains many common categories that are usually worth considering, with an emphasis on business information system needs. The guidelines also suggest some priorities in the analysis. Examples are drawn from the 1) POS, 2) Monopoly, and 3) airline reservation domains.

                                                                                                                                                                                                                                            表 9.1.概念类类别列表。

                                                                                                                                                                                                                                            概念类类别

                                                                                                                                                                                                                                            Conceptual Class Category

                                                                                                                                                                                                                                            例子

                                                                                                                                                                                                                                            Examples

                                                                                                                                                                                                                                            商业交易

                                                                                                                                                                                                                                            business transactions

                                                                                                                                                                                                                                            指南: 这些很关键(它们涉及金钱),因此请从交易开始。

                                                                                                                                                                                                                                            Guideline: These are critical (they involve money), so start with transactions.

                                                                                                                                                                                                                                            销售、付款

                                                                                                                                                                                                                                            Sale, Payment

                                                                                                                                                                                                                                            保留

                                                                                                                                                                                                                                            Reservation

                                                                                                                                                                                                                                            交易行项目

                                                                                                                                                                                                                                            transaction line items

                                                                                                                                                                                                                                            指南: 交易通常附带相关的行项目,因此接下来请考虑这些项目。

                                                                                                                                                                                                                                            Guideline: Transactions often come with related line items, so consider these next.

                                                                                                                                                                                                                                            SalesLineItem 销售行项目

                                                                                                                                                                                                                                            SalesLineItem

                                                                                                                                                                                                                                            与交易或交易行项目相关的产品或服务

                                                                                                                                                                                                                                            product or service related to a transaction or transaction line item

                                                                                                                                                                                                                                            指南: 交易是针对某物(产品或服务)的。接下来考虑这些。

                                                                                                                                                                                                                                            Guideline: Transactions are for something (a product or service). Consider these next.

                                                                                                                                                                                                                                            项目

                                                                                                                                                                                                                                            Item

                                                                                                                                                                                                                                            航班、座位、餐食

                                                                                                                                                                                                                                            Flight, Seat, Meal

                                                                                                                                                                                                                                            交易记录在哪里?

                                                                                                                                                                                                                                            where is the transaction recorded?

                                                                                                                                                                                                                                            指南: 重要。

                                                                                                                                                                                                                                            Guideline: Important.

                                                                                                                                                                                                                                            Register, Ledger

                                                                                                                                                                                                                                            Register, Ledger

                                                                                                                                                                                                                                            FlightManifest (航班清单)

                                                                                                                                                                                                                                            FlightManifest

                                                                                                                                                                                                                                            与交易相关的个人或组织的角色;用例中的参与者

                                                                                                                                                                                                                                            roles of people or organizations related to the transaction; actors in the use case

                                                                                                                                                                                                                                            指南: 我们通常需要了解交易中涉及的各方。

                                                                                                                                                                                                                                            Guideline: We usually need to know about the parties involved in a transaction.

                                                                                                                                                                                                                                            收银员, 客户, 商店 大富翁玩家 乘客, 航空公司

                                                                                                                                                                                                                                            Cashier, Customer, Store MonopolyPlayer Passenger, Airline

                                                                                                                                                                                                                                            交易地点;服务地点

                                                                                                                                                                                                                                            place of transaction; place of service

                                                                                                                                                                                                                                            商店

                                                                                                                                                                                                                                            Store

                                                                                                                                                                                                                                            机场, 飞机, 座位

                                                                                                                                                                                                                                            Airport, Plane, Seat

                                                                                                                                                                                                                                            值得注意的事件,通常有我们需要记住的时间或地点

                                                                                                                                                                                                                                            noteworthy events, often with a time or place we need to remember

                                                                                                                                                                                                                                            销售、支付 MonopolyGame Flight

                                                                                                                                                                                                                                            Sale, Payment MonopolyGame Flight

                                                                                                                                                                                                                                            物理对象

                                                                                                                                                                                                                                            physical objects

                                                                                                                                                                                                                                            指南: 这在创建设备控制软件或仿真时尤其重要。

                                                                                                                                                                                                                                            Guideline: This is especially relevant when creating device-control software, or simulations.

                                                                                                                                                                                                                                            Item, Register Board, Piece, Die 飞机

                                                                                                                                                                                                                                            Item, Register Board, Piece, Die Airplane

                                                                                                                                                                                                                                            事物描述

                                                                                                                                                                                                                                            descriptions of things

                                                                                                                                                                                                                                            指南: 讨论见第 147 页。

                                                                                                                                                                                                                                            Guideline: See p. 147 for discussion.

                                                                                                                                                                                                                                            产品描述

                                                                                                                                                                                                                                            ProductDescription

                                                                                                                                                                                                                                            航班描述

                                                                                                                                                                                                                                            FlightDescription

                                                                                                                                                                                                                                            目录

                                                                                                                                                                                                                                            catalogs

                                                                                                                                                                                                                                            指南: 描述通常位于目录中。

                                                                                                                                                                                                                                            Guideline: Descriptions are often in a catalog.

                                                                                                                                                                                                                                            产品目录

                                                                                                                                                                                                                                            ProductCatalog

                                                                                                                                                                                                                                            航班目录

                                                                                                                                                                                                                                            FlightCatalog

                                                                                                                                                                                                                                            事物容器(物理或信息)

                                                                                                                                                                                                                                            containers of things (physical or information)

                                                                                                                                                                                                                                            商店, Bin Board 飞机

                                                                                                                                                                                                                                            Store, Bin Board Airplane

                                                                                                                                                                                                                                            容器中的事物

                                                                                                                                                                                                                                            things in a container

                                                                                                                                                                                                                                            项目 Square (in a Board) Passenger

                                                                                                                                                                                                                                            Item Square (in a Board) Passenger

                                                                                                                                                                                                                                            其他协作系统

                                                                                                                                                                                                                                            other collaborating systems

                                                                                                                                                                                                                                            信用授权系统

                                                                                                                                                                                                                                            CreditAuthorizationSystem

                                                                                                                                                                                                                                            AirTrafficControl 空中交通管制

                                                                                                                                                                                                                                            AirTrafficControl

                                                                                                                                                                                                                                            财务、工作、合同、法律事务的记录

                                                                                                                                                                                                                                            records of finance, work, contracts, legal matters

                                                                                                                                                                                                                                            收据、分类帐

                                                                                                                                                                                                                                            Receipt, Ledger

                                                                                                                                                                                                                                            维护日志

                                                                                                                                                                                                                                            MaintenanceLog

                                                                                                                                                                                                                                            金融工具

                                                                                                                                                                                                                                            financial instruments

                                                                                                                                                                                                                                            现金、支票、信用额度

                                                                                                                                                                                                                                            Cash, Check, LineOfCredit

                                                                                                                                                                                                                                            TicketCredit (票证积分)

                                                                                                                                                                                                                                            TicketCredit

                                                                                                                                                                                                                                            为了执行工作而经常引用的时间表、手册、文档

                                                                                                                                                                                                                                            schedules, manuals, documents that are regularly referred to in order to perform work

                                                                                                                                                                                                                                            每日价格变更列表

                                                                                                                                                                                                                                            DailyPriceChangeList

                                                                                                                                                                                                                                            维修计划

                                                                                                                                                                                                                                            RepairSchedule



                                                                                                                                                                                                                                            方法 3:使用名词短语标识查找概念类

                                                                                                                                                                                                                                            Method 3: Finding Conceptual Classes with Noun Phrase Identification

                                                                                                                                                                                                                                            [Abbot83] 中建议的另一种有用的技术(因为它很简单)是语言分析:识别域的文本描述中的名词和名词短语,并将它们视为候选的概念类或属性。[5]

                                                                                                                                                                                                                                            Another useful technique (because of its simplicity) suggested in [Abbot83] is linguistic analysis: Identify the nouns and noun phrases in textual descriptions of a domain, and consider them as candidate conceptual classes or attributes.[5]

                                                                                                                                                                                                                                            [5] 语言分析变得更加复杂;它也被称为 Natural Language Modeling 。例如,参见 [Moreno97]。

                                                                                                                                                                                                                                            [5] Linguistic analysis has become more sophisticated; it also goes by the name natural language modeling. See [Moreno97] for example.

                                                                                                                                                                                                                                            指引

                                                                                                                                                                                                                                            Guideline

                                                                                                                                                                                                                                            这种方法必须小心;机械的名词到类映射是不可能的,而且自然语言中的单词是模棱两可的。

                                                                                                                                                                                                                                            Care must be applied with this method; a mechanical noun-to-class mapping isn't possible, and words in natural languages are ambiguous.



                                                                                                                                                                                                                                            然而,语言分析是另一个灵感来源。全副武装的用例是本分析的一个很好的描述。例如,可以使用 Process Sale 用例的当前场景。

                                                                                                                                                                                                                                            Nevertheless, linguistic analysis is another source of inspiration. The fully dressed use cases are an excellent description to draw from for this analysis. For example, the current scenario of the Process Sale use case can be used.

                                                                                                                                                                                                                                            主要成功方案(或基本流程):

                                                                                                                                                                                                                                            Main Success Scenario (or Basic Flow):

                                                                                                                                                                                                                                            1. 客户到达 POS 结账处,并携带要购买的商品和/或服务。

                                                                                                                                                                                                                                            2. Customer arrives at a POS checkout with goods and/or services to purchase.

                                                                                                                                                                                                                                            3. 出纳开始新的销售

                                                                                                                                                                                                                                            4. Cashier starts a new sale.

                                                                                                                                                                                                                                            5. 收银员输入商品标识符

                                                                                                                                                                                                                                            6. Cashier enters item identifier.

                                                                                                                                                                                                                                            7. 系统记录销售行项目并显示项目描述、价格和汇总。根据一组价格规则计算出的价格。

                                                                                                                                                                                                                                            8. System records sale line item and presents item description, price, and running total. Price calculated from a set of price rules.

                                                                                                                                                                                                                                            收银员重复步骤 2-3,直到指示完成。

                                                                                                                                                                                                                                            Cashier repeats steps 2-3 until indicates done.

                                                                                                                                                                                                                                            1. 系统显示计算税款的总额。

                                                                                                                                                                                                                                            2. System presents total with taxes calculated.

                                                                                                                                                                                                                                            3. 收银员告诉客户总数,并要求付款

                                                                                                                                                                                                                                            4. Cashier tells Customer the total, and asks for payment.

                                                                                                                                                                                                                                            5. 客户付款,系统处理付款。

                                                                                                                                                                                                                                            6. Customer pays and System handles payment.

                                                                                                                                                                                                                                            7. 系统记录已完成的销售,并将销售和付款信息发送到外部会计(用于会计和佣金)和库存系统(以更新库存)。

                                                                                                                                                                                                                                            8. System logs the completed sale and sends sale and payment information to the external Accounting (for accounting and commissions) and Inventory systems (to update inventory).

                                                                                                                                                                                                                                            9. 系统出示收据

                                                                                                                                                                                                                                            10. System presents receipt.

                                                                                                                                                                                                                                            11. 客户带着收据和货物(如果有)离开。

                                                                                                                                                                                                                                            12. Customer leaves with receipt and goods (if any).

                                                                                                                                                                                                                                            扩展 (或替代流):

                                                                                                                                                                                                                                            Extensions (or Alternative Flows):

                                                                                                                                                                                                                                            . . .

                                                                                                                                                                                                                                            . . .

                                                                                                                                                                                                                                            7a.现金支付:

                                                                                                                                                                                                                                            1. 出纳输入支付的现金金额

                                                                                                                                                                                                                                            2. 系统显示到期余额,并释放银箱

                                                                                                                                                                                                                                            3. 出纳将现金存入客户,并将余额退还给客户。

                                                                                                                                                                                                                                            4. 系统记录现金支付。

                                                                                                                                                                                                                                            7a. Paying by cash:

                                                                                                                                                                                                                                            1. Cashier enters the cash amount tendered.

                                                                                                                                                                                                                                            2. System presents the balance due, and releases the cash drawer.

                                                                                                                                                                                                                                            3. Cashier deposits cash tendered and returns balance in cash to Customer.

                                                                                                                                                                                                                                            4. System records the cash payment.



                                                                                                                                                                                                                                            域模型是值得注意的域概念和词汇的可视化。这些术语在哪里找到?有些在用例中。其他的则在其他文件中,或者专家的脑海中。无论如何,用例是挖掘名词短语识别的丰富来源。

                                                                                                                                                                                                                                            The domain model is a visualization of noteworthy domain concepts and vocabulary. Where are those terms found? Some are in the use cases. Others are in other documents, or the minds of experts. In any event, use cases are one rich source to mine for noun phrase identification.

                                                                                                                                                                                                                                            这些名词短语中有些是候选的概念类,有些可能指的是在这次迭代中被忽略的概念类(例如,“Accounting”和“commissions”),还有一些可能只是概念类的属性。有关区分两者的建议,请参见第 160 页。

                                                                                                                                                                                                                                            Some of these noun phrases are candidate conceptual classes, some may refer to conceptual classes that are ignored in this iteration (for example, "Accounting" and "commissions"), and some may be simply attributes of conceptual classes. See p. 160 for advice on distinguishing between the two.

                                                                                                                                                                                                                                            这种方法的一个弱点是自然语言的不精确性;不同的名词短语可能代表相同的概念类或属性,以及其他歧义。尽管如此,还是建议将其与 Conceptual Class Category List 技术结合使用。

                                                                                                                                                                                                                                            A weakness of this approach is the imprecision of natural language; different noun phrases may represent the same conceptual class or attribute, among other ambiguities. Nevertheless, it is recommended in combination with the Conceptual Class Category List technique.

                                                                                                                                                                                                                                              9.6. 示例:查找和绘制概念类

                                                                                                                                                                                                                                              9.6. Example: Find and Draw Conceptual Classes

                                                                                                                                                                                                                                              案例研究:POS 域

                                                                                                                                                                                                                                              Case Study: POS Domain

                                                                                                                                                                                                                                              从类别列表和名词短语分析中,生成域的候选概念类列表。由于这是一个商业信息系统,因此我将首先关注强调商业交易及其与其他事物的关系的类别列表指南。该列表仅限于当前正在考虑的 iteration-1 的要求和简化,iteration-1 是 Process Sale 的基本纯现金场景。

                                                                                                                                                                                                                                              From the category list and noun phrase analysis, a list is generated of candidate conceptual classes for the domain. Since this is a business information system, I'll focus first on the category list guidelines that emphasize business transactions and their relationship with other things. The list is constrained to the requirements and simplifications currently under consideration for iteration-1, the basic cash-only scenario of Process Sale.



                                                                                                                                                                                                                                              销售

                                                                                                                                                                                                                                              Sale

                                                                                                                                                                                                                                              出纳员

                                                                                                                                                                                                                                              Cashier

                                                                                                                                                                                                                                              现金支付

                                                                                                                                                                                                                                              CashPayment

                                                                                                                                                                                                                                              客户

                                                                                                                                                                                                                                              Customer

                                                                                                                                                                                                                                              SalesLineItem 销售行项目

                                                                                                                                                                                                                                              SalesLineItem

                                                                                                                                                                                                                                              商店

                                                                                                                                                                                                                                              Store

                                                                                                                                                                                                                                              项目

                                                                                                                                                                                                                                              Item

                                                                                                                                                                                                                                              产品描述

                                                                                                                                                                                                                                              ProductDescription

                                                                                                                                                                                                                                              注册

                                                                                                                                                                                                                                              Register

                                                                                                                                                                                                                                              产品目录

                                                                                                                                                                                                                                              ProductCatalog

                                                                                                                                                                                                                                              分类帐

                                                                                                                                                                                                                                              Ledger

                                                                                                                                                                                                                                               



                                                                                                                                                                                                                                              没有所谓的“正确”列表。这是一个有点武断的抽象和领域词汇的集合,建模者认为值得注意。然而,通过遵循识别策略,不同的建模者将生成类似的列表。

                                                                                                                                                                                                                                              There is no such thing as a "correct" list. It is a somewhat arbitrary collection of abstractions and domain vocabulary that the modelers consider noteworthy. Nevertheless, by following the identification strategies, different modelers will produce similar lists.

                                                                                                                                                                                                                                              在实践中,我不会先创建一个文本列表,而是在发现概念类时立即绘制概念类的 UML 类图。见图 9.7

                                                                                                                                                                                                                                              In practice, I don't create a text list first, but immediately draw a UML class diagram of the conceptual classes as we uncover them. See Figure 9.7.

                                                                                                                                                                                                                                              图 9.7.初始 POS 域模型。



                                                                                                                                                                                                                                              添加关联和属性将在后面的部分中介绍。

                                                                                                                                                                                                                                              Adding the associations and attributes is covered in later sections.

                                                                                                                                                                                                                                              案例研究:垄断域

                                                                                                                                                                                                                                              Case Study: Monopoly Domain

                                                                                                                                                                                                                                              从类别列表和名词短语分析中,我为玩大富翁游戏的迭代 1 简化场景生成了一个候选概念类列表(参见图 9.8)。由于这是一个模拟,因此我强调了域中值得注意的有形物理对象。

                                                                                                                                                                                                                                              From the Category List and noun phrase analysis, I generate a list of candidate conceptual classes for the iteration-1 simplified scenario of Play a Monopoly Game (see Figure 9.8). Since this is a simulation, I emphasize the noteworthy tangible, physical objects in the domain.

                                                                                                                                                                                                                                              图 9.8.初始垄断域模型。





                                                                                                                                                                                                                                                9.7. 指南:敏捷建模绘制类图

                                                                                                                                                                                                                                                9.7. Guideline: Agile ModelingSketching a Class Diagram

                                                                                                                                                                                                                                                请注意图 9.8的 UML 类图中的草图样式,保持类框的底部和右侧是开放的。这使得当我们发现新元素时更容易增加类。尽管我在此书图中对类框进行了分组以使其紧凑,但我将在白板上将它们摊开。

                                                                                                                                                                                                                                                Notice the sketching style in the UML class diagram of Figure 9.8keeping the bottom and right sides of the class boxes open. This makes it easier to grow the classes as we discover new elements. And although I've grouped the class boxes for compactness in this book diagram, on a whiteboard I'll spread them out.

                                                                                                                                                                                                                                                  9.8. 指南:敏捷建模在工具中维护模型?

                                                                                                                                                                                                                                                  9.8. Guideline: Agile ModelingMaintain the Model in a Tool?

                                                                                                                                                                                                                                                  在早期的域建模中错过重要的概念类,并在以后的设计草图或编程中发现它们是正常的。如果您采用敏捷建模方法,则创建域模型的目的是快速理解和传达关键概念的粗略近似值。完美不是目标,敏捷模型通常在创建后不久就被丢弃(尽管如果你用过白板,我建议你拍一张数字快照)。从这个角度来看,没有动力维护或更新模型。但这并不意味着更新模型是错误的。

                                                                                                                                                                                                                                                  It's normal to miss significant conceptual classes during early domain modeling, and to discover them later during design sketching or programming. If you are taking an agile modeling approach, the purpose of creating a domain model is to quickly understand and communicate a rough approximation of the key concepts. Perfection is not the goal, and agile models are usually discarded shortly after creation (although if you've used a whiteboard, I recommend taking a digital snapshot). From this viewpoint, there is no motivation to maintain or update the model. But that doesn't mean it's wrong to update the model.

                                                                                                                                                                                                                                                  如果有人希望用新发现来维护模型和更新模型,那么这是在 UML CASE 工具中重新绘制白板草图的一个很好的理由,或者最初使用工具和计算机投影仪进行绘图(以便其他人轻松查看图表)。但是,问问自己:谁将使用更新的模型,为什么?如果没有实际原因,请不要打扰。通常,软件不断发展的领域层暗示了大多数值得注意的术语,而长寿命的 OO 分析领域模型并不会增加价值。

                                                                                                                                                                                                                                                  If someone wants the model maintained and updated with new discoveries, that's a good reason to redraw the whiteboard sketch within a UML CASE tool, or to originally do the drawing with a tool and a computer projector (for others to see the diagram easily). But, ask yourself: Who is going to use the updated model, and why? If there isn't a practical reason, don't bother. Often, the evolving domain layer of the software hints at most of the noteworthy terms, and a long-life OO analysis domain model doesn't add value.

                                                                                                                                                                                                                                                    9.9. 指南:报表对象在模型中包含 'receipt' ?

                                                                                                                                                                                                                                                    9.9. Guideline: Report ObjectsInclude 'Receipt' in the Model?

                                                                                                                                                                                                                                                    收据是 POS 域中一个值得注意的术语。但也许它只是一份销售和付款报告,因此信息重复。它应该在域模型中吗?

                                                                                                                                                                                                                                                    Receipt is a noteworthy term in the POS domain. But perhaps it's only a report of a sale and payment, and thus duplicate information. Should it be in the domain model?

                                                                                                                                                                                                                                                    以下是一些需要考虑的因素:

                                                                                                                                                                                                                                                    Here are some factors to consider:

                                                                                                                                                                                                                                                    • 通常,在域模型中显示其他信息的报告没有用,因为其所有信息都是从其他来源派生或复制的。这是排除它的原因。

                                                                                                                                                                                                                                                    • In general, showing a report of other information in a domain model is not useful since all its information is derived or duplicated from other sources. This is a reason to exclude it.

                                                                                                                                                                                                                                                    • 另一方面,它在业务规则方面具有特殊的作用:它通常授予(纸质)收据的持有人退回已购买物品的权利。这是在模型中显示它的原因。

                                                                                                                                                                                                                                                    • On the other hand, it has a special role in terms of the business rules: It usually confers the right to the bearer of the (paper) receipt to return bought items. This is a reason to show it in the model.

                                                                                                                                                                                                                                                    由于此迭代中未考虑 item return,因此将排除 Receipt。在处理 Handle Returns 用例的迭代期间,我们有理由将其包含在内。

                                                                                                                                                                                                                                                    Since item returns are not being considered in this iteration, Receipt will be excluded. During the iteration that tackles the Handle Returns use case, we would be justified to include it.

                                                                                                                                                                                                                                                      9.10. 指南:像地图制作者一样思考;使用域术语

                                                                                                                                                                                                                                                      9.10. Guideline: Think Like a Mapmaker; Use Domain Terms

                                                                                                                                                                                                                                                      mapmaker 策略适用于地图模型和域模型。

                                                                                                                                                                                                                                                      The mapmaker strategy applies to both maps and domain models.

                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                      本着制图师或制图者工作的精神制作域模型:

                                                                                                                                                                                                                                                      Make a domain model in the spirit of how a cartographer or mapmaker works:

                                                                                                                                                                                                                                                      • 使用区域中的现有名称。例如,如果为图书馆开发模型,请将客户命名为“借阅者”或“赞助人”,这是图书馆工作人员使用的术语。

                                                                                                                                                                                                                                                      • Use the existing names in the territory. For example, if developing a model for a library, name the customer a "Borrower" or "Patron"the terms used by the library staff.

                                                                                                                                                                                                                                                      • 排除不相关或超出范围的功能。例如,在迭代 1 的 Monopoly 域模型中,不使用卡片(例如“Get out of Jail Free”卡片),因此在此迭代中不要在模型中显示卡片

                                                                                                                                                                                                                                                      • Exclude irrelevant or out-of-scope features. For example, in the Monopoly domain model for iteration-1, cards (such as the "Get out of Jail Free" card) are not used, so don't show a Card in the model this iteration.

                                                                                                                                                                                                                                                      • 不要添加不存在的东西。

                                                                                                                                                                                                                                                      • Do not add things that are not there.



                                                                                                                                                                                                                                                      其原理类似于 Use the Domain Vocabulary 策略 [Coad95]。

                                                                                                                                                                                                                                                      The principle is similar to the Use the Domain Vocabulary strategy [Coad95].

                                                                                                                                                                                                                                                        9.11. 指南:如何对虚幻世界进行建模?

                                                                                                                                                                                                                                                        9.11. Guideline: How to Model the Unreal World?

                                                                                                                                                                                                                                                        一些软件系统适用于在自然域或业务域中很少找到类比的域;电信软件就是一个例子。然而,仍然可以在这些域中创建域模型。它需要高度的抽象,从熟悉的非 OO 设计中退后一步,并仔细倾听领域专家使用的核心词汇和概念。

                                                                                                                                                                                                                                                        Some software systems are for domains that find very little analogy in natural or business domains; software for telecommunications is an example. Yet it is still possible to create a domain model in these domains. It requires a high degree of abstraction, stepping back from familiar non-OO designs, and listening carefully to the core vocabulary and concepts that domain experts use.

                                                                                                                                                                                                                                                        例如,以下是与电信交换机域相关的候选概念类:Message、Connection、Port、Dialog、Route、Protocol

                                                                                                                                                                                                                                                        For example, here are candidate conceptual classes related to the domain of a telecommunication switch: Message, Connection, Port, Dialog, Route, Protocol.

                                                                                                                                                                                                                                                          9.12. 指南:属性与类的常见错误

                                                                                                                                                                                                                                                          9.12. Guideline: A Common Mistake with Attributes vs. Classes

                                                                                                                                                                                                                                                          也许在创建域模型时最常见的错误是将某物表示为属性,而它本应是一个概念类。帮助防止此错误的经验法则是:

                                                                                                                                                                                                                                                          Perhaps the most common mistake when creating a domain model is to represent something as an attribute when it should have been a conceptual class. A rule of thumb to help prevent this mistake is:

                                                                                                                                                                                                                                                          指引

                                                                                                                                                                                                                                                          Guideline

                                                                                                                                                                                                                                                          如果我们不将某个概念类 X 视为现实世界中的数字或文本,那么 X 可能是一个概念类,而不是一个属性。

                                                                                                                                                                                                                                                          If we do not think of some conceptual class X as a number or text in the real world, X is probably a conceptual class, not an attribute.



                                                                                                                                                                                                                                                          例如,store 应该是 Sale 的属性,还是单独的概念类 Store

                                                                                                                                                                                                                                                          As an example, should store be an attribute of Sale, or a separate conceptual class Store?

                                                                                                                                                                                                                                                          在现实世界中,商店不被视为数字或文本该术语表示法人实体、组织和占用空间的事物。因此,Store 应该是一个概念类。

                                                                                                                                                                                                                                                          In the real world, a store is not considered a number or textthe term suggests a legal entity, an organization, and something that occupies space. Therefore, Store should be a conceptual class.

                                                                                                                                                                                                                                                          再举一个例子,考虑 air reservations 的域。destination 应该是 Flight 的属性,还是单独的概念类 Airport

                                                                                                                                                                                                                                                          As another example, consider the domain of airline reservations. Should destination be an attribute of Flight, or a separate conceptual class Airport?

                                                                                                                                                                                                                                                          在现实世界中,目的地机场不被视为数字或文本,它是一个占用空间的巨大东西。因此,机场应该是一个概念。

                                                                                                                                                                                                                                                          In the real world, a destination airport is not considered a number or textit is a massive thing that occupies space. Therefore, Airport should be a concept.

                                                                                                                                                                                                                                                            9.13. 指南:何时使用 'Description' 类进行建模?

                                                                                                                                                                                                                                                            9.13. Guideline: When to Model with 'Description' Classes?

                                                                                                                                                                                                                                                            描述类包含描述其他内容的信息。例如,记录 Item 的价格、图片和文本描述的 ProductDescription。这在 [Coad92] 中首次被命名为 Item-Descriptor 模式。

                                                                                                                                                                                                                                                            A description class contains information that describes something else. For example, a ProductDescription that records the price, picture, and text description of an Item. This was first named the Item-Descriptor pattern in [Coad92].

                                                                                                                                                                                                                                                            动机:为什么使用 'description' 类?

                                                                                                                                                                                                                                                            Motivation: Why Use 'Description' Classes?

                                                                                                                                                                                                                                                            以下讨论乍一看似乎与一个罕见的、高度专业化的问题有关。但是,事实证明,在许多域模型中,对描述类的需求很常见。

                                                                                                                                                                                                                                                            The following discussion may at first seem related to a rare, highly specialized issue. However, it turns out that the need for description classes is common in many domain models.

                                                                                                                                                                                                                                                            假设以下内容:

                                                                                                                                                                                                                                                            Assume the following:

                                                                                                                                                                                                                                                            • 一个 Item 实例表示 store 中的一个物理项目;因此,它甚至可能具有序列号。

                                                                                                                                                                                                                                                            • An Item instance represents a physical item in a store; as such, it may even have a serial number.

                                                                                                                                                                                                                                                            • Item 具有 description、price 和 itemID,它们不会记录在其他任何位置。

                                                                                                                                                                                                                                                            • An Item has a description, price, and itemID, which are not recorded anywhere else.

                                                                                                                                                                                                                                                            • 在商店工作的每个人都患有健忘症。

                                                                                                                                                                                                                                                            • Everyone working in the store has amnesia.

                                                                                                                                                                                                                                                            • 每次售出真正的实物商品时,都会从“软件土地”中删除相应的 Item 软件实例。

                                                                                                                                                                                                                                                            • Every time a real physical item is sold, a corresponding software instance of Item is deleted from "software land."

                                                                                                                                                                                                                                                            有了这些假设,以下方案会发生什么情况?

                                                                                                                                                                                                                                                            With these assumptions, what happens in the following scenario?

                                                                                                                                                                                                                                                            对流行的新素食 burgerObjectBurger 有强烈的需求。商店售罄,这意味着 ObjectBurgers 的所有 Item 实例都已从计算机内存中删除。

                                                                                                                                                                                                                                                            There is strong demand for the popular new vegetarian burgerObjectBurger. The store sells out, implying that all Item instances of ObjectBurgers are deleted from computer memory.

                                                                                                                                                                                                                                                            现在,这里有一个问题:如果有人问,“ObjectBurgers 要多少钱?”,没有人能回答,因为他们的价格内存是附加到库存实例的,这些实例在出售时被删除了。

                                                                                                                                                                                                                                                            Now, here is one problem: If someone asks, "How much do ObjectBurgers cost?", no one can answer, because the memory of their price was attached to inventoried instances, which were deleted as they were sold.

                                                                                                                                                                                                                                                            以下是一些相关问题:如果该模型在类似于域模型的软件中实现,则具有重复的数据,空间效率低下,并且容易出错(由于信息复制),因为同一产品的每个 Item 实例的描述、价格和 itemID 都是重复的。

                                                                                                                                                                                                                                                            Here are some related problems: The model, if implemented in software similar to the domain model, has duplicate data, is space-inefficient, and error-prone (due to replicated information) because the description, price, and itemID are duplicated for every Item instance of the same product.

                                                                                                                                                                                                                                                            前面的问题说明了需要作为其他事物的描述(有时称为规范)的对象。要解决 Item 问题,需要一个 ProductDescription 类来记录有关项的信息。ProductDescription 不表示 Item,它表示有关项的信息的描述。参见图 9.9

                                                                                                                                                                                                                                                            The preceding problem illustrates the need for objects that are descriptions (sometimes called specifications) of other things. To solve the Item problem, what is needed is a ProductDescription class that records information about items. A ProductDescription does not represent an Item, it represents a description of information about items. See Figure 9.9.

                                                                                                                                                                                                                                                            图 9.9.关于其他事物的描述。* 表示 “many” 的多重性。它表示一个 ProductDescription 可以描述许多 (*)



                                                                                                                                                                                                                                                            特定 Item 可能具有序列号;它表示一个物理实例。ProductDescription 没有序列号。

                                                                                                                                                                                                                                                            A particular Item may have a serial number; it represents a physical instance. A ProductDescription wouldn't have a serial number.

                                                                                                                                                                                                                                                            从概念角度切换到软件角度,请注意,即使所有库存项目都已售出,并且删除了其相应的项目软件实例,ProductDescription 仍会保留。

                                                                                                                                                                                                                                                            Switching from a conceptual to a software perspective, note that even if all inventoried items are sold and their corresponding Item software instances are deleted, the ProductDescription still remains.

                                                                                                                                                                                                                                                            在销售、产品和服务域中,通常需要描述类。这在制造业中也很常见,这需要对制造物进行不同于事物本身的描述

                                                                                                                                                                                                                                                            The need for description classes is common in sales, product, and service domains. It is also common in manufacturing, which requires a description of a manufactured thing that is distinct from the thing itself.

                                                                                                                                                                                                                                                            指南:描述类在什么情况下有用?

                                                                                                                                                                                                                                                            Guideline: When Are Description Classes Useful?

                                                                                                                                                                                                                                                            指引

                                                                                                                                                                                                                                                            Guideline

                                                                                                                                                                                                                                                            在以下情况下添加描述类(例如 ProductDescription):

                                                                                                                                                                                                                                                            Add a description class (for example, ProductDescription) when:

                                                                                                                                                                                                                                                            • 需要有关于项目或服务的描述,独立于这些项目或服务的当前存在。

                                                                                                                                                                                                                                                            • There needs to be a description about an item or service, independent of the current existence of any examples of those items or services.

                                                                                                                                                                                                                                                            • 删除它们描述的事物的实例(例如 Item)会导致需要维护但与已删除事物错误关联的信息丢失。

                                                                                                                                                                                                                                                            • Deleting instances of things they describe (for example, Item) results in a loss of information that needs to be maintained, but was incorrectly associated with the deleted thing.

                                                                                                                                                                                                                                                            • 它减少了冗余或重复的信息。

                                                                                                                                                                                                                                                            • It reduces redundant or duplicated information.



                                                                                                                                                                                                                                                            示例:Airline 域中的描述

                                                                                                                                                                                                                                                            Example: Descriptions in the Airline Domain

                                                                                                                                                                                                                                                            再举一个例子,考虑一家航空公司的一架飞机发生致命坠毁。假设所有航班都被取消了六个月,等待调查完成。此外,假设当航班取消时,其相应的 Flight 软件对象将从计算机内存中删除。因此,在崩溃后,所有 Flight 软件对象都将被删除。

                                                                                                                                                                                                                                                            As another example, consider an airline company that suffers a fatal crash of one of its planes. Assume that all the flights are cancelled for six months pending completion of an investigation. Also assume that when flights are cancelled, their corresponding Flight software objects are deleted from computer memory. Therefore, after the crash, all Flight software objects are deleted.

                                                                                                                                                                                                                                                            如果航班去往哪个机场的唯一记录是在 Flight 软件实例中,这些实例表示特定日期和时间的特定航班,则不再有航空公司拥有哪些航线的记录。

                                                                                                                                                                                                                                                            If the only record of what airport a flight goes to is in the Flight software instances, which represent specific flights for a particular date and time, then there is no longer a record of what flight routes the airline has.

                                                                                                                                                                                                                                                            这个问题可以从领域模型中的纯概念角度和软件设计中的软件角度来解决,使用描述航班及其路线的 FlightDescription,即使特定航班没有计划(参见图 9.10)。

                                                                                                                                                                                                                                                            The problem can be solved, both from a purely conceptual perspective in a domain model and from a software perspective in the software designs, with a FlightDescription that describes a flight and its route, even when a particular flight is not scheduled (see Figure 9.10).

                                                                                                                                                                                                                                                            图 9.10.关于其他事物的描述。



                                                                                                                                                                                                                                                            请注意,前面的示例是关于服务 (航班) 而不是商品 (例如 veggieburger)。通常需要服务或服务计划的描述。

                                                                                                                                                                                                                                                            Note that the prior example is about a service (a flight) rather than a good (such as a veggieburger). Descriptions of services or service plans are commonly needed.

                                                                                                                                                                                                                                                            再举一个例子,一家移动电话公司销售诸如 “bronze”、“gold” 等的软件包。有必要将套餐描述的概念(一种描述每分钟费率、无线 Internet 内容、成本等的服务计划)与实际销售套餐的概念(例如“2047 年 1 月 1 日以每月 55 美元的价格出售给 Craig Larman”的黄金套餐)分开。营销部门需要先定义并记录此服务计划或 MobileCommunicationsPackageDescription,然后才能销售。

                                                                                                                                                                                                                                                            As another example, a mobile phone company sells packages such as "bronze," "gold," and so forth. It is necessary to have the concept of a description of the package (a kind of service plan describing rates per minute, wireless Internet content, the cost, and so forth) separate from the concept of an actual sold package (such as "gold package sold to Craig Larman on Jan. 1, 2047 at $55 per month"). Marketing needs to define and record this service plan or MobileCommunicationsPackageDescription before any are sold.

                                                                                                                                                                                                                                                              9.14. 关联

                                                                                                                                                                                                                                                              9.14. Associations

                                                                                                                                                                                                                                                              查找和显示满足当前正在开发的方案的信息要求所需的关联非常有用,这有助于了解域。

                                                                                                                                                                                                                                                              It's useful to find and show associations that are needed to satisfy the information requirements of the current scenarios under development, and which aid in understanding the domain.

                                                                                                                                                                                                                                                              关联是类(更准确地说,这些类的实例)之间的关系,它表示一些有意义和有趣的联系(参见图 9.11)。

                                                                                                                                                                                                                                                              An association is a relationship between classes (more precisely, instances of those classes) that indicates some meaningful and interesting connection (see Figure 9.11).

                                                                                                                                                                                                                                                              图 9.11.协会。



                                                                                                                                                                                                                                                              在 UML 中,关联被定义为“两个或多个分类器之间的语义关系,这些分类器涉及其实例之间的连接”。

                                                                                                                                                                                                                                                              In the UML, associations are defined as "the semantic relationship between two or more classifiers that involve connections among their instances."

                                                                                                                                                                                                                                                              指南:何时显示关联?

                                                                                                                                                                                                                                                              Guideline: When to Show an Association?

                                                                                                                                                                                                                                                              值得注意的关联通常意味着知道需要保留一段时间的关系,可能是毫秒或几年,具体取决于上下文。换句话说,在哪些对象之间,我们需要一些关系的记忆

                                                                                                                                                                                                                                                              Associations worth noting usually imply knowledge of a relationship that needs to be preserved for some durationit could be milliseconds or years, depending on context. In other words, between what objects do we need some memory of a relationship?

                                                                                                                                                                                                                                                              例如,我们是否需要记住哪些 SalesLineItem 实例与 Sale 实例相关联?当然,否则就不可能重建销售、打印收据或计算销售总额。

                                                                                                                                                                                                                                                              For example, do we need to remember what SalesLineItem instances are associated with a Sale instance? Definitely, otherwise it would not be possible to reconstruct a sale, print a receipt, or calculate a sale total.

                                                                                                                                                                                                                                                              我们需要在分类账中记住已完成的 Sales,用于会计和法律目的。

                                                                                                                                                                                                                                                              And we need to remember completed Sales in a Ledger, for accounting and legal purposes.

                                                                                                                                                                                                                                                              因为领域模型是一个概念视角,所以这些关于需要记住的陈述指的是现实世界中的需求,而不是软件需求,尽管在实现过程中会出现许多相同的需求。

                                                                                                                                                                                                                                                              Because the domain model is a conceptual perspective, these statements about the need to remember refer to a need in a real situation of the world, not a software need, although during implementation many of the same needs will arise.

                                                                                                                                                                                                                                                              在大富翁领域,我们需要记住棋(或玩家)在游戏中的方格是什么,如果不记住它,那就不起作用。同样,我们需要记住特定 Player 拥有的 Piece 是什么。我们需要记住哪些方格是特定的一部分。

                                                                                                                                                                                                                                                              In the monopoly domain, we need to remember what Square a Piece (or Player) is onthe game doesn't work if that isn't remembered. Likewise, we need to remember what Piece is owned by a particular Player. We need to remember what Squares are part of a particular Board.

                                                                                                                                                                                                                                                              但另一方面,无需记住 Die (或复数的 “dice”) 总数表示要移动到的 Square。这是真的,但我们不需要在搬家之后对这一事实有持续的记忆。同样,收银员可以查找 ProductDescriptions,但无需记住特定收银员查找特定 ProductDescriptions 的事实。

                                                                                                                                                                                                                                                              But on the other hand, there is no need to remember that the Die (or the plural, "dice") total indicates the Square to move to. It's true, but we don't need to have an ongoing memory of that fact, after the move has been made. Likewise, a Cashier may look up ProductDescriptions, but there is no need to remember the fact of a particular Cashier looking up particular ProductDescriptions.

                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                              请考虑在域模型中包括以下关联:

                                                                                                                                                                                                                                                              Consider including the following associations in a domain model:

                                                                                                                                                                                                                                                              • 需要将关系知识保留一段时间的关联(“需要记住”关联)。

                                                                                                                                                                                                                                                              • Associations for which knowledge of the relationship needs to be preserved for some duration ("need-to-remember" associations).

                                                                                                                                                                                                                                                              • 从 Common Associations List 派生的关联。

                                                                                                                                                                                                                                                              • Associations derived from the Common Associations List.



                                                                                                                                                                                                                                                              指南:为什么我们应该避免添加许多关联?

                                                                                                                                                                                                                                                              Guideline: Why Should We Avoid Adding Many Associations?

                                                                                                                                                                                                                                                              我们需要避免向域模型添加太多关联。回顾我们的离散数学研究,您可能还记得,在具有 n 个节点的图中,可以有 (n·(n-1))/2 关联到其他节点可能非常大的数量。具有 20 个类的域模型可以有 190 个关联线!图表上的许多线条会用 “视觉噪声” 遮挡它。因此,请谨慎添加关联行。使用本章中建议的准则指南,并专注于 “need-to-remember” 关联。

                                                                                                                                                                                                                                                              We need to avoid adding too many associations to a domain model. Digging back into our discrete mathematics studies, you may recall that in a graph with n nodes, there can be (n·(n-1))/2 associations to other nodesa potentially very large number. A domain model with 20 classes could have 190 associations lines! Many lines on the diagram will obscure it with "visual noise." Therefore, be parsimonious about adding association lines. Use the criterion guidelines suggested in this chapter, and focus on "need-to-remember" associations.

                                                                                                                                                                                                                                                              观点:这些关联会在软件中实现吗?

                                                                                                                                                                                                                                                              Perspectives: Will the Associations Be Implemented In Software?

                                                                                                                                                                                                                                                              在域建模期间,关联不是关于软件解决方案中的数据流、数据库外键关系、实例变量或对象连接的声明;它表明,在真实领域中,关系在纯粹的概念角度中是有意义的。

                                                                                                                                                                                                                                                              During domain modeling, an association is not a statement about data flows, database foreign key relationships, instance variables, or object connections in a software solution; it is a statement that a relationship is meaningful in a purely conceptual perspectivein the real domain.

                                                                                                                                                                                                                                                              也就是说,其中许多关系将在软件中作为导航和可见性路径实现(在 Design Model 和 Data Model 中)。但域模型不是数据模型;添加关联是为了突出我们对值得注意的关系的粗略理解,而不是为了记录对象或数据结构。

                                                                                                                                                                                                                                                              That said, many of these relationships will be implemented in software as paths of navigation and visibility (both in the Design Model and Data Model). But the domain model is not a data model; associations are added to highlight our rough understanding of noteworthy relationships, not to document object or data structures.

                                                                                                                                                                                                                                                              应用 UML:关联表示法

                                                                                                                                                                                                                                                              Applying UML: Association Notation

                                                                                                                                                                                                                                                              关联表示为具有大写关联名称的类之间的一条线。参见图 9.12

                                                                                                                                                                                                                                                              An association is represented as a line between classes with a capitalized association name. See Figure 9.12.

                                                                                                                                                                                                                                                              图 9.12.关联的 UML 表示法。



                                                                                                                                                                                                                                                              关联的末端可以包含一个多重性表达式,该表达式指示类实例之间的数值关系。

                                                                                                                                                                                                                                                              The ends of an association may contain a multiplicity expression indicating the numerical relationship between instances of the classes.

                                                                                                                                                                                                                                                              这种关联本质上是双向的,这意味着从任一类的实例到另一个类的逻辑遍历都是可能的。这种遍历是纯粹抽象的;它不是关于软件实体之间连接的声明。

                                                                                                                                                                                                                                                              The association is inherently bidirectional, meaning that from instances of either class, logical traversal to the other is possible. This traversal is purely abstract; it is not a statement about connections between software entities.

                                                                                                                                                                                                                                                              可选的“读取方向箭头”指示读取关联名称的方向;它不指示可见性或导航的方向。如果箭头不存在,则约定是从左到右或从上到下读取关联,尽管 UML 没有将此作为规则(参见图 9.12)。

                                                                                                                                                                                                                                                              An optional "reading direction arrow" indicates the direction to read the association name; it does not indicate direction of visibility or navigation. If the arrow is not present, the convention is to read the association from left to right or top to bottom, although the UML does not make this a rule (see Figure 9.12).

                                                                                                                                                                                                                                                              谨慎

                                                                                                                                                                                                                                                              Caution

                                                                                                                                                                                                                                                              读取方向箭头在模型方面没有意义;它只是对图表读者的帮助。

                                                                                                                                                                                                                                                              The reading direction arrow has no meaning in terms of the model; it is only an aid to the reader of the diagram.



                                                                                                                                                                                                                                                              指南:如何在 UML 中命名关联?

                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                              根据 ClassName-VerbPhrase-ClassName 格式命名关联,其中动词短语创建可读且有意义的序列。

                                                                                                                                                                                                                                                              Name an association based on a ClassName-VerbPhrase-ClassName format where the verb phrase creates a sequence that is readable and meaningful.



                                                                                                                                                                                                                                                              简单的关联名称(如 “Has” 或 “Uses”) 通常很差,因为它们很少增强我们对域的理解。

                                                                                                                                                                                                                                                              Simple association names such as "Has" or "Uses" are usually poor, as they seldom enhance our understanding of the domain.

                                                                                                                                                                                                                                                              例如

                                                                                                                                                                                                                                                              For example,

                                                                                                                                                                                                                                                              • 销售 Paid-by Cash付款

                                                                                                                                                                                                                                                                • 错误示例(不会增强含义):销售使用 CashPayment

                                                                                                                                                                                                                                                              • Sale Paid-by CashPayment

                                                                                                                                                                                                                                                                • bad example (doesn't enhance meaning): Sale Uses CashPayment

                                                                                                                                                                                                                                                              • 玩家在场

                                                                                                                                                                                                                                                                • 坏例子(不增强含义):玩家有 Square

                                                                                                                                                                                                                                                              • Player Is-on Square

                                                                                                                                                                                                                                                                • bad example (doesn't enhance meaning): Player Has Square

                                                                                                                                                                                                                                                              关联名称应以大写字母开头,因为关联表示实例之间链接的分类器;在 UML 中,分类器应以大写字母开头。复合关联名称的两种常见且同样合法的格式是:

                                                                                                                                                                                                                                                              Association names should start with a capital letter, since an association represents a classifier of links between instances; in the UML, classifiers should start with a capital letter. Two common and equally legal formats for a compound association name are:

                                                                                                                                                                                                                                                              • 记录 - 当前

                                                                                                                                                                                                                                                              • Records-current

                                                                                                                                                                                                                                                              • 记录当前

                                                                                                                                                                                                                                                              • RecordsCurrent

                                                                                                                                                                                                                                                              应用 UML:角色

                                                                                                                                                                                                                                                              Applying UML: Roles

                                                                                                                                                                                                                                                              关联的每一端称为角色。角色可以选择具有:

                                                                                                                                                                                                                                                              Each end of an association is called a role. Roles may optionally have:

                                                                                                                                                                                                                                                              • 多重性表达式

                                                                                                                                                                                                                                                              • multiplicity expression

                                                                                                                                                                                                                                                              • 名字

                                                                                                                                                                                                                                                              • name

                                                                                                                                                                                                                                                              • 可导航性

                                                                                                                                                                                                                                                              • navigability

                                                                                                                                                                                                                                                              接下来研究多重性。

                                                                                                                                                                                                                                                              Multiplicity is examined next.

                                                                                                                                                                                                                                                              应用 UML:多重性

                                                                                                                                                                                                                                                              Applying UML: Multiplicity

                                                                                                                                                                                                                                                              多重性定义了一个类 A 的多少个实例可以与一个类 B 的一个实例相关联(参见图 9.13)。

                                                                                                                                                                                                                                                              Multiplicity defines how many instances of a class A can be associated with one instance of a class B (see Figure 9.13).

                                                                                                                                                                                                                                                              图 9.13.关联的多重性。



                                                                                                                                                                                                                                                              例如,Store 的单个实例可以与“多个”(零个或多个,由 * 表示)Item 实例相关联。

                                                                                                                                                                                                                                                              For example, a single instance of a Store can be associated with "many" (zero or more, indicated by the *) Item instances.

                                                                                                                                                                                                                                                              多重性表达式的一些示例如图 9.14 所示。

                                                                                                                                                                                                                                                              Some examples of multiplicity expressions are shown in Figure 9.14.

                                                                                                                                                                                                                                                              图 9.14.多重性值。



                                                                                                                                                                                                                                                              重数值表示在特定时刻(而不是在一段时间内)可以有效地与另一个实例关联的实例数。例如,随着时间的推移,二手车可能会反复卖回给二手车经销商。但在任何特定时刻,这辆车都只由一家经销商备货。这辆车在任何特定时刻都没有被许多经销商备货。同样,在实行一夫一妻制的国家,一个人在任何特定时刻只能与另一个结婚,即使在一段时间内,同一个人可能与许多人结婚。

                                                                                                                                                                                                                                                              The multiplicity value communicates how many instances can be validly associated with another, at a particular moment, rather than over a span of time. For example, it is possible that a used car could be repeatedly sold back to used car dealers over time. But at any particular moment, the car is only Stocked-by one dealer. The car is not Stocked-by many dealers at any particular moment. Similarly, in countries with monogamy laws, a person can be Married-to only one other person at any particular moment, even though over a span of time, that same person may be married to many persons.

                                                                                                                                                                                                                                                              多重性值取决于我们作为建模者和软件开发人员的兴趣,因为它传达了一个将(或可能)反映在软件中的域约束。有关示例和解释,请参见图 9.15

                                                                                                                                                                                                                                                              The multiplicity value is dependent on our interest as a modeler and software developer, because it communicates a domain constraint that will be (or could be) reflected in software. See Figure 9.15 for an example and explanation.

                                                                                                                                                                                                                                                              图 9.15.多重性取决于上下文。



                                                                                                                                                                                                                                                              Rumbaugh 举了另一个例子,即 Works-for association [Rumbaugh91] 中的个人公司。指示 Person 实例是否适用于一个或多个 Company 实例取决于模型的上下文;税务部门对许多人感兴趣;一个工会可能只有一个。选择通常取决于我们构建软件的原因。

                                                                                                                                                                                                                                                              Rumbaugh gives another example of Person and Company in the Works-for association [Rumbaugh91]. Indicating if a Person instance works for one or many Company instances is dependent on the context of the model; the tax department is interested in many; a union probably only one. The choice usually depends on why we are building the software.

                                                                                                                                                                                                                                                              应用 UML:两个类之间的多个关联

                                                                                                                                                                                                                                                              Applying UML: Multiple Associations Between Two Classes

                                                                                                                                                                                                                                                              在 UML 类图中,两个类之间可能具有多个关联;这种情况并不少见。在 POS 或 Monopoly 案例研究中没有突出的例子,但航空公司领域的一个例子是 Flight(或者更准确地说,FlightLeg)和 Airport 之间的关系(见图 9.16);Flying-To 和 Flying-from 关联是截然不同的关系,应单独显示。

                                                                                                                                                                                                                                                              Two classes may have multiple associations between them in a UML class diagram; this is not uncommon. There is no outstanding example in the POS or Monopoly case study, but an example from the domain of the airline is the relationships between a Flight (or perhaps more precisely, a FlightLeg) and an Airport (see Figure 9.16); the flying-to and flying-from associations are distinctly different relationships, which should be shown separately.

                                                                                                                                                                                                                                                              图 9.16.多个关联。



                                                                                                                                                                                                                                                              指南:如何使用公共关联列表查找关联

                                                                                                                                                                                                                                                              Guideline: How to Find Associations with a Common Associations List

                                                                                                                                                                                                                                                              使用 Table 9.2 中的列表开始添加关联。它包含值得考虑的常见类别,尤其是对于业务信息系统。示例来自 1) POS、2) Monopoly 和 3) 航空公司预订域。

                                                                                                                                                                                                                                                              Start the addition of associations by using the list in Table 9.2. It contains common categories that are worth considering, especially for business information systems. Examples are drawn from the 1) POS, 2) Monopoly, and 3) airline reservation domains.

                                                                                                                                                                                                                                                              表 9.2.常见关联列表。

                                                                                                                                                                                                                                                              类别

                                                                                                                                                                                                                                                              Category

                                                                                                                                                                                                                                                              例子

                                                                                                                                                                                                                                                              Examples

                                                                                                                                                                                                                                                              A 是与另一个交易 B 相关的交易

                                                                                                                                                                                                                                                              A is a transaction related to another transaction B

                                                                                                                                                                                                                                                              现金付款销售

                                                                                                                                                                                                                                                              CashPaymentSale

                                                                                                                                                                                                                                                              取消预订

                                                                                                                                                                                                                                                              CancellationReservation

                                                                                                                                                                                                                                                              A 是交易 B 的行项目

                                                                                                                                                                                                                                                              A is a line item of a transaction B

                                                                                                                                                                                                                                                              SalesLineItem销售

                                                                                                                                                                                                                                                              SalesLineItemSale

                                                                                                                                                                                                                                                              A 是交易(或订单项)的产品或服务 B

                                                                                                                                                                                                                                                              A is a product or service for a transaction (or line item) B

                                                                                                                                                                                                                                                              ItemSalesLineItem(或 Sale)

                                                                                                                                                                                                                                                              ItemSalesLineItem (or Sale)

                                                                                                                                                                                                                                                              航班预订

                                                                                                                                                                                                                                                              FlightReservation

                                                                                                                                                                                                                                                              A 是与交易 B 相关的角色

                                                                                                                                                                                                                                                              A is a role related to a transaction B

                                                                                                                                                                                                                                                              客户付款

                                                                                                                                                                                                                                                              CustomerPayment

                                                                                                                                                                                                                                                              乘客票

                                                                                                                                                                                                                                                              PassengerTicket

                                                                                                                                                                                                                                                              A 是 B 的物理或逻辑部分

                                                                                                                                                                                                                                                              A is a physical or logical part of B

                                                                                                                                                                                                                                                              Drawer 注册

                                                                                                                                                                                                                                                              DrawerRegister

                                                                                                                                                                                                                                                              方形板

                                                                                                                                                                                                                                                              SquareBoard

                                                                                                                                                                                                                                                              座椅飞机

                                                                                                                                                                                                                                                              SeatAirplane

                                                                                                                                                                                                                                                              A 在物理上或逻辑上包含在 B 中/在 B 上

                                                                                                                                                                                                                                                              A is physically or logically contained in/on B

                                                                                                                                                                                                                                                              RegisterStore、ItemShelf

                                                                                                                                                                                                                                                              RegisterStore, ItemShelf

                                                                                                                                                                                                                                                              方形板

                                                                                                                                                                                                                                                              SquareBoard

                                                                                                                                                                                                                                                              乘客飞机

                                                                                                                                                                                                                                                              PassengerAirplane

                                                                                                                                                                                                                                                              A 是 B 的说明

                                                                                                                                                                                                                                                              A is a description for B

                                                                                                                                                                                                                                                              ProductDescriptionItem

                                                                                                                                                                                                                                                              ProductDescriptionItem

                                                                                                                                                                                                                                                              航班描述航班

                                                                                                                                                                                                                                                              FlightDescriptionFlight

                                                                                                                                                                                                                                                              A 在 B 中已知/记录/记录/报告/捕获

                                                                                                                                                                                                                                                              A is known/logged/recorded/reported/captured in B

                                                                                                                                                                                                                                                              销售注册

                                                                                                                                                                                                                                                              SaleRegister

                                                                                                                                                                                                                                                              块方块

                                                                                                                                                                                                                                                              PieceSquare

                                                                                                                                                                                                                                                              ReservationFlightManifest

                                                                                                                                                                                                                                                              ReservationFlightManifest

                                                                                                                                                                                                                                                              A 是 B 的成员

                                                                                                                                                                                                                                                              A is a member of B

                                                                                                                                                                                                                                                              收银员商店

                                                                                                                                                                                                                                                              CashierStore

                                                                                                                                                                                                                                                              玩家大富翁游戏

                                                                                                                                                                                                                                                              PlayerMonopolyGame

                                                                                                                                                                                                                                                              飞行员航空公司

                                                                                                                                                                                                                                                              PilotAirline

                                                                                                                                                                                                                                                              A 是 B 的组织子单位

                                                                                                                                                                                                                                                              A is an organizational subunit of B

                                                                                                                                                                                                                                                              百货公司

                                                                                                                                                                                                                                                              DepartmentStore

                                                                                                                                                                                                                                                              维修航空公司

                                                                                                                                                                                                                                                              MaintenanceAirline

                                                                                                                                                                                                                                                              A 使用或管理或拥有 B

                                                                                                                                                                                                                                                              A uses or manages or owns B

                                                                                                                                                                                                                                                              收银员注册

                                                                                                                                                                                                                                                              CashierRegister

                                                                                                                                                                                                                                                              PlayerPiece 播放器

                                                                                                                                                                                                                                                              PlayerPiece

                                                                                                                                                                                                                                                              飞行员飞机

                                                                                                                                                                                                                                                              PilotAirplane

                                                                                                                                                                                                                                                              A 紧挨着 B

                                                                                                                                                                                                                                                              A is next to B

                                                                                                                                                                                                                                                              SalesLineItemSalesLineItem

                                                                                                                                                                                                                                                              SalesLineItemSalesLineItem

                                                                                                                                                                                                                                                              正方形

                                                                                                                                                                                                                                                              SquareSquare

                                                                                                                                                                                                                                                              城市城市

                                                                                                                                                                                                                                                              CityCity



                                                                                                                                                                                                                                                                9.15. 示例:域模型中的关联

                                                                                                                                                                                                                                                                9.15. Example: Associations in the Domain Models

                                                                                                                                                                                                                                                                案例研究:NextGen POS

                                                                                                                                                                                                                                                                Case Study: NextGen POS

                                                                                                                                                                                                                                                                图 9.17 中的域模型显示了一组概念类和关联,它们是 POS 域模型的候选项。这些关联主要源自此迭代要求的 “need-to-remember” 标准和 Common Association List。阅读列表并将示例映射到图表应该可以解释这些选择。例如:

                                                                                                                                                                                                                                                                The domain model in Figure 9.17 shows a set of conceptual classes and associations that are candidates for our POS domain model. The associations are primarily derived from the "need-to-remember" criteria of this iteration requirements, and the Common Association List. Reading the list and mapping the examples to the diagram should explain the choices. For example:

                                                                                                                                                                                                                                                                • 与另一笔交易 Sale Paid-by CashPayment 相关的交易。

                                                                                                                                                                                                                                                                • Transactions related to another transaction Sale Paid-by CashPayment.

                                                                                                                                                                                                                                                                • 交易 Sale 的行项目包含 SalesLineItem

                                                                                                                                                                                                                                                                • Line items of a transaction Sale Contains SalesLineItem.

                                                                                                                                                                                                                                                                • 交易(或行项目)的产品 SalesLineItem Records-sale-of Item

                                                                                                                                                                                                                                                                • Product for a transaction (or line item) SalesLineItem Records-sale-of Item.

                                                                                                                                                                                                                                                                图 9.17.NextGen POS 部分域模型。



                                                                                                                                                                                                                                                                案例研究:垄断

                                                                                                                                                                                                                                                                Case Study: Monopoly

                                                                                                                                                                                                                                                                参见图 9.18。同样,这些关联主要源自此迭代要求的 “need-to-remember” 标准和 Common Association List。例如:

                                                                                                                                                                                                                                                                See Figure 9.18. Again, the associations are primarily derived from the "need-to-remember" criteria of this iteration requirements, and the Common Association List. For example:

                                                                                                                                                                                                                                                                • A 包含在 B 板包含正方形中或位于 B

                                                                                                                                                                                                                                                                • A is contained in or on B Board Contains Square.

                                                                                                                                                                                                                                                                • A 拥有 B 玩家拥有棋子

                                                                                                                                                                                                                                                                • A owns B Players Owns Piece.

                                                                                                                                                                                                                                                                • A 在 B Piece Is-on Square 中已知。

                                                                                                                                                                                                                                                                • A is known in/on B Piece Is-on Square.

                                                                                                                                                                                                                                                                • A 是 B Player 的成员 MonopolyGame(或玩 BigpolyGame)。

                                                                                                                                                                                                                                                                • A is member of B Player Member-of (or Plays) MonopolyGame.

                                                                                                                                                                                                                                                                图 9.18.垄断部分域模型。



                                                                                                                                                                                                                                                                  9.16. 属性

                                                                                                                                                                                                                                                                  9.16. Attributes

                                                                                                                                                                                                                                                                  确定满足当前正在开发的方案的信息要求所需的概念类的那些属性非常有用。属性是对象的逻辑数据值。

                                                                                                                                                                                                                                                                  It is useful to identify those attributes of conceptual classes that are needed to satisfy the information requirements of the current scenarios under development. An attribute is a logical data value of an object.

                                                                                                                                                                                                                                                                  指南:何时显示属性?

                                                                                                                                                                                                                                                                  Guideline: When to Show Attributes?

                                                                                                                                                                                                                                                                  包括要求 (例如,用例) 建议或暗示需要记住信息的属性。

                                                                                                                                                                                                                                                                  Include attributes that the requirements (for example, use cases) suggest or imply a need to remember information.

                                                                                                                                                                                                                                                                  例如,Process Sale 用例中的收据(报告销售信息)通常包括日期和时间、商店名称和地址以及收银员 ID 等。

                                                                                                                                                                                                                                                                  For example, a receipt (which reports the information of a sale) in the Process Sale use case normally includes a date and time, the store name and address, and the cashier ID, among many other things.

                                                                                                                                                                                                                                                                  因此

                                                                                                                                                                                                                                                                  Therefore,

                                                                                                                                                                                                                                                                  • Sale 需要 dateTime 属性。

                                                                                                                                                                                                                                                                  • Sale needs a dateTime attribute.

                                                                                                                                                                                                                                                                  • Store 需要名称和地址

                                                                                                                                                                                                                                                                  • Store needs a name and address.

                                                                                                                                                                                                                                                                  • 收银员需要 ID

                                                                                                                                                                                                                                                                  • Cashier needs an ID.

                                                                                                                                                                                                                                                                  应用 UML:属性表示法

                                                                                                                                                                                                                                                                  Applying UML: Attribute Notation

                                                                                                                                                                                                                                                                  属性显示在 class 框的第二个隔间中(参见图 9.19)。可以选择显示它们的类型和其他信息。

                                                                                                                                                                                                                                                                  Attributes are shown in the second compartment of the class box (see Figure 9.19). Their type and other information may optionally be shown.

                                                                                                                                                                                                                                                                  图 9.19.类和属性。



                                                                                                                                                                                                                                                                  更多表示法

                                                                                                                                                                                                                                                                  UML 中属性的完整语法为:

                                                                                                                                                                                                                                                                  The full syntax for an attribute in the UML is:

                                                                                                                                                                                                                                                                  可见性名称 : 类型 multiplicity = default {property-string}

                                                                                                                                                                                                                                                                  visibility name : type multiplicity = default {property-string}

                                                                                                                                                                                                                                                                  详细的 UML 类图符号,第 249 页,以及本书的封底内侧

                                                                                                                                                                                                                                                                  detailed UML class diagram notation p. 249, and also on the back inside cover of the book



                                                                                                                                                                                                                                                                  一些常见的例子如图 9.20 所示。

                                                                                                                                                                                                                                                                  Some common examples are shown in Figure 9.20.

                                                                                                                                                                                                                                                                  图 9.20.UML 中的属性表示法。



                                                                                                                                                                                                                                                                  按照惯例,除非另有说明,否则大多数建模者都会假设属性具有私有可见性 (-),因此我通常不会绘制显式可见性符号。

                                                                                                                                                                                                                                                                  As a convention, most modelers will assume attributes have private visibility (-) unless shown otherwise, so I don't usually draw an explicit visibility symbol.

                                                                                                                                                                                                                                                                  {readOnly} 可能是 attributes 最常见的属性字符串。

                                                                                                                                                                                                                                                                  {readOnly} is probably the most common property string for attributes.

                                                                                                                                                                                                                                                                  多重性可用于指示值的可选存在,或可以填充 (collection) 属性的对象数。例如,许多域要求知道一个人的名字和姓氏,但中间名是可选的。表达式 middleName : [0..1] 表示存在可选的 value0 或 1 值。

                                                                                                                                                                                                                                                                  Multiplicity can be used to indicate the optional presence of a value, or the number of objects that can fill a (collection) attribute. For example, many domains require that a first and last name be known for a person, but that a middle name is optional. The expression middleName : [0..1] indicates an optional value0 or 1 values are present.

                                                                                                                                                                                                                                                                  指南:在哪里记录属性要求?

                                                                                                                                                                                                                                                                  请注意,middleName : [0..1] 是嵌入在域模型中的需求或域规则。尽管这只是一个概念视角的领域模型,但它可能意味着软件视角应该允许 UI、对象和数据库中的 middleName 缺失值。一些建模者接受只在领域模型中保留这样的规范,但我发现这很容易出错且分散,因为人们往往不会详细查看领域模型,也不会寻求需求指导。他们通常也不维护域模型。

                                                                                                                                                                                                                                                                  Notice that, subtly, middleName : [0..1] is a requirement or domain rule, embedded in the domain model. Although this is just a conceptual-perspective domain model, it probably implies that the software perspective should allow a missing value for middleName in the UI, the objects, and the database. Some modellers accept leaving such specifications only in the domain model, but I find this error-prone and scattered, as people tend to not look at the domain model in detail, or for requirements guidance. Nor do they usually maintain the domain model.

                                                                                                                                                                                                                                                                  相反,我建议将所有此类属性要求放在 UP Glossary 中,它用作数据字典。也许我花了一个小时与领域专家一起绘制了领域模型;之后,我可以花 15 分钟浏览它并将隐含的属性要求转移到 Glossary 中。

                                                                                                                                                                                                                                                                  Instead, I suggest placing all such attribute requirements in the UP Glossary, which serves as a data dictionary. Perhaps I've spent an hour sketching a domain model with a domain expert; afterwards, I can spend 15 minutes looking through it and transferring implied attribute requirements into the Glossary.

                                                                                                                                                                                                                                                                  另一种选择是使用将 UML 模型与数据字典集成的工具;然后所有属性将自动显示为 Dictionary 元素。

                                                                                                                                                                                                                                                                  Another alternative is to use a tool that integrates UML models with a data dictionary; then all attributes will automatically show up as dictionary elements.

                                                                                                                                                                                                                                                                  派生属性

                                                                                                                                                                                                                                                                  Sale 中的 total 属性可以计算或从 SalesLineItems 中的信息派生。当我们想传达 1) 这是一个值得注意的属性,但 2) 它是可派生的时,我们使用 UML 约定:在属性名称之前加上 / 符号。

                                                                                                                                                                                                                                                                  The total attribute in the Sale can be calculated or derived from the information in the SalesLineItems. When we want to communicate that 1) this is a noteworthy attribute, but 2) it is derivable, we use the UML convention: a / symbol before the attribute name.

                                                                                                                                                                                                                                                                  再举一个例子,收银员可以接收一组类似的商品(例如,六个豆腐包),输入一次 itemID,然后输入一个数量(例如,六个)。因此,单个 SalesLineItem 可以与项目的多个实例相关联。

                                                                                                                                                                                                                                                                  As another example, a cashier can receive a group of like items (for example, six tofu packages), enter the itemID once, and then enter a quantity (for example, six). Consequently, an individual SalesLineItem can be associated with more than one instance of an item.

                                                                                                                                                                                                                                                                  收银员输入的数量可以记录为 SalesLineItem 的属性(图 9.21)。但是,数量可以根据关联的实际多重性值计算出来,因此它可以被描述为可能从其他信息派生的派生属性。

                                                                                                                                                                                                                                                                  The quantity that is entered by the cashier may be recorded as an attribute of the SalesLineItem (Figure 9.21). However, the quantity can be calculated from the actual multiplicity value of the association, so it may be characterized as a derived attributeone that may be derived from other information.

                                                                                                                                                                                                                                                                  图 9.21.记录行项目中销售的商品数量。



                                                                                                                                                                                                                                                                  指南:什么是合适的属性类型?

                                                                                                                                                                                                                                                                  Guideline: What are Suitable Attribute Types?

                                                                                                                                                                                                                                                                  关注域模型中的数据类型属性

                                                                                                                                                                                                                                                                  非正式地,大多数属性类型应该是通常被认为是“原始”数据类型的类型,例如数字和布尔值。属性的类型通常不应是复杂的域概念,如 SaleAirport

                                                                                                                                                                                                                                                                  Informally, most attribute types should be what are often thought of as "primitive" data types, such as numbers and booleans. The type of an attribute should not normally be a complex domain concept, such as a Sale or Airport.

                                                                                                                                                                                                                                                                  例如,图 9.22Cashier 类中的 currentRegister 属性是不可取的,因为它的类型应该是 Register,而 Register 不是简单的数据类型(例如 NumberString)。表示 Cashier 使用 Register 的最有用方法是使用关联,而不是使用属性。

                                                                                                                                                                                                                                                                  For example, the currentRegister attribute in the Cashier class in Figure 9.22 is undesirable because its type is meant to be a Register, which is not a simple data type (such as Number or String). The most useful way to express that a Cashier uses a Register is with an association, not with an attribute.

                                                                                                                                                                                                                                                                  图 9.22.与关联相关,而不是属性相关。



                                                                                                                                                                                                                                                                  指引

                                                                                                                                                                                                                                                                  Guideline

                                                                                                                                                                                                                                                                  域模型中的属性最好是数据类型。非常常见的数据类型包括:布尔值、日期(或日期时间)、数字、字符、字符串(文本)、时间。

                                                                                                                                                                                                                                                                  The attributes in a domain model should preferably be data types. Very common data types include: Boolean, Date (or DateTime), Number, Character, String (Text), Time.

                                                                                                                                                                                                                                                                  其他常见类型包括:地址、颜色、几何(点、矩形)、电话号码、社会保险号、通用产品代码 (UPC)、SKU、邮政编码、枚举类型

                                                                                                                                                                                                                                                                  Other common types include: Address, Color, Geometrics (Point, Rectangle), Phone Number, Social Security Number, Universal Product Code (UPC), SKU, ZIP or postal codes, enumerated types



                                                                                                                                                                                                                                                                  重复前面的示例,一个常见的混淆是将复杂域概念建模为属性。举例来说,目的地机场并不是一个真正的字符串;它是一个复杂的事物,占据了许多平方公里的空间。因此,Flight 应该通过关联而不是属性与 Airport 相关联,如图 9.23 所示。

                                                                                                                                                                                                                                                                  To repeat an earlier example, a common confusion is modeling a complex domain concept as an attribute. To illustrate, a destination airport is not really a string; it is a complex thing that occupies many square kilometers of space. Therefore, Flight should be related to Airport via an association, not with an attribute, as shown in Figure 9.23.

                                                                                                                                                                                                                                                                  图 9.23.不要将复杂概念显示为属性;使用关联。



                                                                                                                                                                                                                                                                  指引

                                                                                                                                                                                                                                                                  Guideline

                                                                                                                                                                                                                                                                  将概念类与关联(而不是属性)相关联。

                                                                                                                                                                                                                                                                  Relate conceptual classes with an association, not with an attribute.



                                                                                                                                                                                                                                                                  数据类型

                                                                                                                                                                                                                                                                  如前所述,域模型中的属性通常应该是数据类型;非正式地,这些是 “原始” 类型,例如数字、布尔值、字符、字符串和枚举 (例如 Size = {small, large}) 。更准确地说,这是一个 UML 术语,它意味着一组唯一标识没有意义的值(在我们的模型或系统的上下文中)[RJB99]。换句话说,相等性测试不是基于身份,而是基于价值。[6] 例如,区分以下两者(通常)没有意义:

                                                                                                                                                                                                                                                                  As said, attributes in the domain model should generally be data types; informally these are "primitive" types such as number, boolean, character, string, and enumerations (such as Size = {small, large}). More precisely, this is a UML term that implies a set of values for which unique identity is not meaningful (in the context of our model or system) [RJB99]. Said another way, equality tests are not based on identity, but instead on value.[6] For example, it is not (usually) meaningful to distinguish between:

                                                                                                                                                                                                                                                                  [6]例如,在 Java 中,使用 equals 方法完成值测试,使用 == 运算符完成标识测试。

                                                                                                                                                                                                                                                                  [6] In Java, for example, a value test is done with the equals method, and an identity test with the == operator.

                                                                                                                                                                                                                                                                  • Integer 5 的单独实例。

                                                                                                                                                                                                                                                                  • Separate instances of the Integer 5.

                                                                                                                                                                                                                                                                  • 字符串 'cat' 的单独实例。

                                                                                                                                                                                                                                                                  • Separate instances of the String 'cat'.

                                                                                                                                                                                                                                                                  • 日期 “Nov. 13, 1990” 的单独实例。

                                                                                                                                                                                                                                                                  • Separate instance of the Date "Nov. 13, 1990".

                                                                                                                                                                                                                                                                  相比之下,区分(通过对象标识)两个名称均为“Jill Smith”的单独 Person 实例有意义的,因为这两个实例可以表示具有相同名称的单独个人。

                                                                                                                                                                                                                                                                  By contrast, it is meaningful to distinguish (by object identity) between two separate Person instances whose names are both "Jill Smith" because the two instances can represent separate individuals with the same name.

                                                                                                                                                                                                                                                                  此外,数据类型值通常是不可变的。例如,Integer 的实例 '5' 是不可变的;Date 的实例 “Nov. 13, 1990” 可能是不可变的。另一方面,Person 实例的 lastName 可能会因各种原因而更改。

                                                                                                                                                                                                                                                                  Also, data type values are usually immutable. For example, the instance '5' of Integer is immutable; the instance "Nov. 13, 1990" of Date is probably immutable. On the other hand, a Person instance may have its lastName changed for various reasons.

                                                                                                                                                                                                                                                                  从软件的角度来看,很少有情况会比较 IntegerDate 实例的内存地址(标识);只有基于价值的比较才相关。另一方面,可以想象 Person 实例的内存地址可以进行比较和区分,即使它们具有相同的属性值,因为它们的唯一标识很重要。

                                                                                                                                                                                                                                                                  From a software perspective, there are few situations where one would compare the memory addresses (identity) of instances of Integer or Date; only value-based comparisons are relevant. On the other hand, the memory addresses of Person instances could conceivably be compared and distinguished, even if they had the same attribute values, because their unique identity is important.

                                                                                                                                                                                                                                                                  一些 OO 和 UML 建模书籍还谈到了值对象,这些对象与数据类型非常相似,但变化很小。但是,我发现这些区别相当模糊和微妙,因此不要强调它。

                                                                                                                                                                                                                                                                  Some OO and UML modeling books also speak of value objects, which are very similar to data types, but with minor variations. However, I found the distinctions rather fuzzy and subtle, and don't stress it.

                                                                                                                                                                                                                                                                  观点:代码中的属性呢?

                                                                                                                                                                                                                                                                  域模型中的属性主要为数据类型的建议并不意味着 C# 或 Java 属性必须只属于简单的原始数据类型。域模型是一个概念视角,而不是软件视角。在设计模型中,属性可以是任何类型。

                                                                                                                                                                                                                                                                  The recommendation that attributes in the domain model be mainly data types does not imply that C# or Java attributes must only be of simple, primitive data types. The domain model is a conceptual perspective, not a software one. In the Design Model, attributes may be of any type.

                                                                                                                                                                                                                                                                  指南:何时定义新的数据类型类?

                                                                                                                                                                                                                                                                  Guideline: When to Define New Data Type Classes?

                                                                                                                                                                                                                                                                  在 NextGen POS 系统中,需要 itemID 属性;它可能是 ItemProductDescription 的属性。随便看,它似乎只是一个数字或字符串。例如,itemID : IntegeritemID : String

                                                                                                                                                                                                                                                                  In the NextGen POS system an itemID attribute is needed; it is probably an attribute of an Item or ProductDescription. Casually, it seems like just a number or perhaps a string. For example, itemID : Integer or itemID : String.

                                                                                                                                                                                                                                                                  但不仅如此(项标识符具有子部分),实际上,在域模型中具有名为 ItemID(或 ItemIdentifier)的类并指定属性的类型是有用的。例如,itemID : ItemIdentifier

                                                                                                                                                                                                                                                                  But it is more than that (item identifiers have subparts), and in fact it is useful to have a class named ItemID (or ItemIdentifier) in the domain model, and designate the type of the attribute as such. For example, itemID : ItemIdentifier.

                                                                                                                                                                                                                                                                  Table 9.3 提供了使用数据类型进行建模时有用的准则。

                                                                                                                                                                                                                                                                  Table 9.3 provides guidelines when it's useful to model with data types.

                                                                                                                                                                                                                                                                  表 9.3.数据类型建模准则。

                                                                                                                                                                                                                                                                  指引

                                                                                                                                                                                                                                                                  Guideline

                                                                                                                                                                                                                                                                  在以下情况下,将最初可能被视为数字或字符串的内容表示为域模型中的新数据类型类:

                                                                                                                                                                                                                                                                  Represent what may initially be considered a number or string as a new data type class in the domain model if:

                                                                                                                                                                                                                                                                  • 它由单独的部分组成。

                                                                                                                                                                                                                                                                    • 电话号码、人名

                                                                                                                                                                                                                                                                  • It is composed of separate sections.

                                                                                                                                                                                                                                                                    • phone number, name of person

                                                                                                                                                                                                                                                                  • 有与之关联的操作,例如解析或验证。

                                                                                                                                                                                                                                                                    • 社会安全号码

                                                                                                                                                                                                                                                                  • There are operations associated with it, such as parsing or validation.

                                                                                                                                                                                                                                                                    • social security number

                                                                                                                                                                                                                                                                  • 它还有其他属性。

                                                                                                                                                                                                                                                                    • 促销价格可以有开始(生效)日期和结束日期

                                                                                                                                                                                                                                                                  • It has other attributes.

                                                                                                                                                                                                                                                                    • promotional price could have a start (effective) date and end date

                                                                                                                                                                                                                                                                  • 它是一个带有单位的数量。

                                                                                                                                                                                                                                                                    • 付款金额具有货币单位

                                                                                                                                                                                                                                                                  • It is a quantity with a unit.

                                                                                                                                                                                                                                                                    • payment amount has a unit of currency

                                                                                                                                                                                                                                                                  • 它是具有其中一些品质的一个或多个类型的抽象。

                                                                                                                                                                                                                                                                    • 销售域中的商品标识码是通用商品代码 (UPC) 和欧洲商品编码 (EAN) 等类型的泛化

                                                                                                                                                                                                                                                                  • It is an abstraction of one or more types with some of these qualities.

                                                                                                                                                                                                                                                                    • item identifier in the sales domain is a generalization of types such as Universal Product Code (UPC) and European Article Number (EAN)



                                                                                                                                                                                                                                                                  将这些准则应用于 POS 域模型属性将产生以下分析:

                                                                                                                                                                                                                                                                  Applying these guidelines to the POS domain model attributes yields the following analysis:

                                                                                                                                                                                                                                                                  • 项目标识符是各种常见编码方案的抽象,包括 UPC-A、UPC-E 和 EAN 方案系列。这些数字编码方案具有标识制造商、产品、国家/地区(用于 EAN)的子部分,以及用于验证的校验和数字。因此,应该有一个数据类型 ItemID 类,因为它满足上述许多准则。

                                                                                                                                                                                                                                                                  • The item identifier is an abstraction of various common coding schemes, including UPC-A, UPC-E, and the family of EAN schemes. These numeric coding schemes have subparts identifying the manufacturer, product, country (for EAN), and a check-sum digit for validation. Therefore, there should be a data type ItemID class, because it satisfies many of the guidelines above.

                                                                                                                                                                                                                                                                  • priceamount 属性应为数据类型 Money 类,因为它们是以货币单位表示的数量。

                                                                                                                                                                                                                                                                  • The price and amount attributes should be a data type Money class because they are quantities in a unit of currency.

                                                                                                                                                                                                                                                                  • address 属性应该是数据类型 Address 类,因为它有单独的部分。

                                                                                                                                                                                                                                                                  • The address attribute should be a data type Address class because it has separate sections.

                                                                                                                                                                                                                                                                  应用 UML:在哪里说明这些数据类型类?

                                                                                                                                                                                                                                                                  ItemID 类是否应该在域模型中显示为单独的类?这取决于你想在图中强调什么。由于 ItemID 是一种数据类型(实例的唯一标识不用于相等性测试),它可能仅显示在类框的属性隔间中,如图 9.24 所示。另一方面,如果 ItemID 是具有自己的属性和关联的新类型,则将其显示为概念类在其自己的框中可能会提供信息。没有正确的答案;分辨率取决于域模型如何用作通信工具,以及概念在域中的重要性。

                                                                                                                                                                                                                                                                  Should the ItemID class be shown as a separate class in a domain model? It depends on what you want to emphasize in the diagram. Since ItemID is a data type (unique identity of instances is not used for equality testing), it may be shown only in the attribute compartment of the class box, as shown in Figure 9.24. On the other hand, if ItemID is a new type with its own attributes and associations, showing it as a conceptual class in its own box may be informative. There is no correct answer; resolution depends on how the domain model is being used as a tool of communication, and the significance of the concept in the domain.

                                                                                                                                                                                                                                                                  图 9.24.指示对象的数据类型属性的两种方法。



                                                                                                                                                                                                                                                                  指南:没有表示外键的属性

                                                                                                                                                                                                                                                                  Guideline: No Attributes Representing Foreign Keys

                                                                                                                                                                                                                                                                  属性不应用于关联域模型中的概念类。违反此原则的最常见情况是添加一种外键属性,这在关系数据库设计中通常采用的方式,以便关联两种类型。例如,在图 9.25 中,Cashier 类中的 currentRegisterNumber 属性是不可取的,因为它的目的是将 CashierRegister 对象相关联。表示 Cashier 使用 Register 的更好方法是使用关联,而不是使用外键属性。同样,将类型与关联而不是属性关联。

                                                                                                                                                                                                                                                                  Attributes should not be used to relate conceptual classes in the domain model. The most common violation of this principle is to add a kind of foreign key attribute, as is typically done in relational database designs, in order to associate two types. For example, in Figure 9.25 the currentRegisterNumber attribute in the Cashier class is undesirable because its purpose is to relate the Cashier to a Register object. The better way to express that a Cashier uses a Register is with an association, not with a foreign key attribute. Once again, relate types with an association, not with an attribute.

                                                                                                                                                                                                                                                                  图 9.25.不要将属性用作外键。



                                                                                                                                                                                                                                                                  有很多方法可以关联对象外键是 one,我们将把如何实现关系推迟到设计后,以避免设计蠕变

                                                                                                                                                                                                                                                                  There are many ways to relate objectsforeign keys being oneand we will defer how to implement the relation until design to avoid design creep.

                                                                                                                                                                                                                                                                  指南:数量和单位建模

                                                                                                                                                                                                                                                                  Guideline: Modeling Quantities and Units

                                                                                                                                                                                                                                                                  大多数数字数量不应表示为纯数字。考虑价格或重量。说“价格是 13”或“重量是 37”并不能说明什么。欧元?公斤?

                                                                                                                                                                                                                                                                  Most numeric quantities should not be represented as plain numbers. Consider price or weight. Saying "the price was 13" or "the weight was 37" doesn't say much. Euros? Kilograms?

                                                                                                                                                                                                                                                                  这些是具有关联单位的数量,通常需要了解该单位才能支持转换。NextGen POS 软件适用于国际市场,需要支持多种货币的价格。域模型(和软件)应该巧妙地对数量进行建模。

                                                                                                                                                                                                                                                                  These are quantities with associated units, and it is common to require knowledge of the unit to support conversions. The NextGen POS software is for an international market and needs to support prices in multiple currencies. The domain model (and the software) should model quantities skillfully.

                                                                                                                                                                                                                                                                  在一般情况下,解决方案是将 Quantity 表示为一个不同的类,并带有一个关联的 Unit [Fowler96]。显示 Quantity 专业化也很常见。货币是一种以货币为单位的数量。Weight 是包含千克或磅等单位的数量。见图 9.26

                                                                                                                                                                                                                                                                  In the general case, the solution is to represent Quantity as a distinct class, with an associated Unit [Fowler96]. It is also common to show Quantity specializations. Money is a kind of quantity whose units are currencies. Weight is a quantity with units such as kilograms or pounds. See Figure 9.26.

                                                                                                                                                                                                                                                                  图 9.26.对数量进行建模。



                                                                                                                                                                                                                                                                    9.17. 示例:域模型中的属性

                                                                                                                                                                                                                                                                    9.17. Example: Attributes in the Domain Models

                                                                                                                                                                                                                                                                    案例研究:NextGen POS

                                                                                                                                                                                                                                                                    Case Study: NextGen POS

                                                                                                                                                                                                                                                                    参见图 9.27。所选属性反映了此迭代的信息要求,即此迭代的 Process Sale only cash-only 方案。例如:

                                                                                                                                                                                                                                                                    See Figure 9.27. The attributes chosen reflect the information requirements for this iterationthe Process Sale cash-only scenarios of this iteration. For example:

                                                                                                                                                                                                                                                                    现金支付

                                                                                                                                                                                                                                                                    CashPayment

                                                                                                                                                                                                                                                                    已招标金额要确定是否提供了足够的付款并计算零钱,必须捕获金额(也称为“支付金额”)。

                                                                                                                                                                                                                                                                    amountTendered To determine if sufficient payment was provided, and to calculate change, an amount (also known as "amount tendered") must be captured.

                                                                                                                                                                                                                                                                    产品描述

                                                                                                                                                                                                                                                                    Product-Description

                                                                                                                                                                                                                                                                    描述在显示屏或收据上显示说明。

                                                                                                                                                                                                                                                                    description To show the description on a display or receipt.

                                                                                                                                                                                                                                                                    项目 ID查找 ProductDescription

                                                                                                                                                                                                                                                                    itemId To look up a ProductDescription.

                                                                                                                                                                                                                                                                    价格计算销售总额并显示行项目价格。

                                                                                                                                                                                                                                                                    price To calculate the sales total, and show the line item price.

                                                                                                                                                                                                                                                                    销售

                                                                                                                                                                                                                                                                    Sale

                                                                                                                                                                                                                                                                    日期时间收据通常显示销售日期和时间,这对于销售分析很有用。

                                                                                                                                                                                                                                                                    dateTime A receipt normally shows date and time of sale, and this is useful for sales analysis.

                                                                                                                                                                                                                                                                    SalesLineItem 销售行项目

                                                                                                                                                                                                                                                                    SalesLineItem

                                                                                                                                                                                                                                                                    数量当行商品销售中有多个商品(例如,包豆腐)时,记录输入的数量。

                                                                                                                                                                                                                                                                    quantity To record the quantity entered, when there is more than one item in a line item sale (for example, five packages of tofu).

                                                                                                                                                                                                                                                                    商店

                                                                                                                                                                                                                                                                    Store

                                                                                                                                                                                                                                                                    地址、姓名收据需要商店的名称和地址。

                                                                                                                                                                                                                                                                    address, name The receipt requires the name and address of the store.



                                                                                                                                                                                                                                                                    图 9.27.NextGen POS 部分域模型。



                                                                                                                                                                                                                                                                    案例研究:垄断

                                                                                                                                                                                                                                                                    Case Study: Monopoly

                                                                                                                                                                                                                                                                    图 9.28。选择的属性反映了此迭代的信息要求,即此迭代的简化 Play Monopoly Game 场景。例如:

                                                                                                                                                                                                                                                                    See Figure 9.28. The attributes chosen reflect the information requirements for this iterationthe simplified Play Monopoly Game scenario of this iteration. For example:

                                                                                                                                                                                                                                                                    Die

                                                                                                                                                                                                                                                                    faceValue掷骰子后,需要计算移动的距离。

                                                                                                                                                                                                                                                                    faceValue After rolling the dice, needed to calculate the distance of a move.

                                                                                                                                                                                                                                                                    广场

                                                                                                                                                                                                                                                                    Square

                                                                                                                                                                                                                                                                    名字打印所需的跟踪输出。

                                                                                                                                                                                                                                                                    name To print the desired trace output.



                                                                                                                                                                                                                                                                    图 9.28.垄断部分域模型。



                                                                                                                                                                                                                                                                      9.18. 结论:域模型正确吗?

                                                                                                                                                                                                                                                                      9.18. Conclusion: Is the Domain Model Correct?

                                                                                                                                                                                                                                                                      没有单一的正确域模型。所有模型都是我们试图理解的域的近似值;域模型主要是特定组之间理解和交流的工具。一个有用的领域模型可以捕获在当前需求的上下文中理解领域所需的基本抽象和信息,并帮助人们理解领域的概念、术语和关系。

                                                                                                                                                                                                                                                                      There is no such thing as a single correct domain model. All models are approximations of the domain we are attempting to understand; the domain model is primarily a tool of understanding and communication among a particular group. A useful domain model captures the essential abstractions and information required to understand the domain in the context of the current requirements, and aids people in understanding the domainits concepts, terminology, and relationships.

                                                                                                                                                                                                                                                                        9.19. 过程:迭代和进化域建模

                                                                                                                                                                                                                                                                        9.19. Process: Iterative and Evolutionary Domain Modeling

                                                                                                                                                                                                                                                                        尽管自相矛盾的是,有大量的篇幅专门用于解释领域建模,但在有经验的人中,每次迭代中(部分、进化的)模型的开发可能只需要 30 分钟。通过使用预定义的分析模式,可以进一步缩短这一时间。

                                                                                                                                                                                                                                                                        Although paradoxically a significant number of pages were devoted to explaining domain modeling, in experienced hands the development of a (partial, evolutionary) model in each iteration may take only 30 minutes. This is further shortened by the use of predefined analysis patterns.

                                                                                                                                                                                                                                                                        在迭代开发中,我们通过多次迭代逐步发展领域模型。在每个场景中,域模型仅限于正在考虑的先前和当前场景,而不是扩展到“大爆炸”瀑布式模型,该模型在早期试图捕获所有可能的概念类和关系。例如,此 POS 迭代仅限于简化的纯现金流程销售场景;因此,将创建一个部分域模型来反映这一点,而不是更多。

                                                                                                                                                                                                                                                                        In iterative development, we incrementally evolve a domain model over several iterations. In each, the domain model is limited to the prior and current scenarios under consideration, rather than expanding to a "big bang" waterfall-style model that early on attempts to capture all possible conceptual classes and relationships. For example, this POS iteration is limited to a simplified cash-only Process Sale scenario; therefore, a partial domain model will be created to reflect just thatnot more.

                                                                                                                                                                                                                                                                        并重申本章开头的建议:

                                                                                                                                                                                                                                                                        And to reiterate advice from the start of this chapter:

                                                                                                                                                                                                                                                                        指引

                                                                                                                                                                                                                                                                        Guideline

                                                                                                                                                                                                                                                                        避免瀑布式的大建模工作来制作一个彻底或 “正确” 的领域模型,这也永远不会,而且这种过度建模工作会导致分析瘫痪,投资回报很少或没有。

                                                                                                                                                                                                                                                                        Avoid a waterfall-mindset big-modeling effort to make a thorough or "correct" domain modelit won't ever be either, and such over-modeling efforts lead to analysis paralysis, with little or no return on the investment.

                                                                                                                                                                                                                                                                        将域建模限制为每次迭代不超过几个小时。

                                                                                                                                                                                                                                                                        Limit domain modeling to no more than a few hours per iteration.



                                                                                                                                                                                                                                                                        UP 中的域模型

                                                                                                                                                                                                                                                                        Domain Models Within the UP

                                                                                                                                                                                                                                                                        表 9.4 的示例所示,UP 域模型通常在细化阶段开始和完成。

                                                                                                                                                                                                                                                                        As suggested in the example of Table 9.4, the UP Domain Model is usually both started and completed in the elaboration phase.

                                                                                                                                                                                                                                                                        表 9.4.UP 伪影和计时示例。s - 开始;R - 优化

                                                                                                                                                                                                                                                                        学科

                                                                                                                                                                                                                                                                        Discipline

                                                                                                                                                                                                                                                                        人工制品

                                                                                                                                                                                                                                                                        Artifact

                                                                                                                                                                                                                                                                        因塞普。

                                                                                                                                                                                                                                                                        Incep.

                                                                                                                                                                                                                                                                        埃拉布。

                                                                                                                                                                                                                                                                        Elab.

                                                                                                                                                                                                                                                                        常量。

                                                                                                                                                                                                                                                                        Const.

                                                                                                                                                                                                                                                                        反式。

                                                                                                                                                                                                                                                                        Trans.

                                                                                                                                                                                                                                                                        迭 代

                                                                                                                                                                                                                                                                        Iteration

                                                                                                                                                                                                                                                                        I1

                                                                                                                                                                                                                                                                        E1..中文

                                                                                                                                                                                                                                                                        E1..En

                                                                                                                                                                                                                                                                        C1..快递 之 家

                                                                                                                                                                                                                                                                        C1..Cn

                                                                                                                                                                                                                                                                        T1..T2 航站楼

                                                                                                                                                                                                                                                                        T1..T2

                                                                                                                                                                                                                                                                        业务建模

                                                                                                                                                                                                                                                                        Business Modeling

                                                                                                                                                                                                                                                                        域模型

                                                                                                                                                                                                                                                                        Domain Model

                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        要求

                                                                                                                                                                                                                                                                        Requirements

                                                                                                                                                                                                                                                                        用例模型 (SSD)

                                                                                                                                                                                                                                                                        Use-Case Model (SSDs)

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        视觉

                                                                                                                                                                                                                                                                        Vision

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        补充规格

                                                                                                                                                                                                                                                                        Supplementary Specification

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        词汇表

                                                                                                                                                                                                                                                                        Glossary

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        设计

                                                                                                                                                                                                                                                                        Design

                                                                                                                                                                                                                                                                        设计模型

                                                                                                                                                                                                                                                                        Design Model

                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                        软件架构文档

                                                                                                                                                                                                                                                                        SW Architecture Document

                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                        数据模型

                                                                                                                                                                                                                                                                        Data Model

                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        s

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                        r

                                                                                                                                                                                                                                                                         





                                                                                                                                                                                                                                                                        初始

                                                                                                                                                                                                                                                                        领域模型在开始时并没有强烈的动机,因为 inception 的目的不是进行严肃的调查,而是决定项目是否值得在阐述阶段进行更深入的调查。

                                                                                                                                                                                                                                                                        Domain models are not strongly motivated in inception, since inception's purpose is not to do a serious investigation, but rather to decide if the project is worth deeper investigation in an elaboration phase.

                                                                                                                                                                                                                                                                        阐述

                                                                                                                                                                                                                                                                        域模型主要是在细化迭代期间创建的,此时最需要理解值得注意的概念并在设计工作期间将一些概念映射到软件类。

                                                                                                                                                                                                                                                                        The Domain Model is primarily created during elaboration iterations, when the need is highest to understand the noteworthy concepts and map some to software classes during design work.

                                                                                                                                                                                                                                                                        UP 业务对象模型与域模型

                                                                                                                                                                                                                                                                        UP 域模型是不太常见的 UP 业务对象模型 (BOM) 的官方变体。UP BOM不要与 BOM 的许多其他定义混淆是一种描述整个业务的企业模型。它可以在进行业务流程工程或再工程时使用,独立于任何一个软件应用程序(例如 NextGen POS)。引用:

                                                                                                                                                                                                                                                                        The UP Domain Model is an official variation of the less common UP Business Object Model (BOM). The UP BOMnot to be confused with the many other definitions of a BOMis a kind of enterprise model that describes the entire business. It may be used when doing business process engineering or reengineering, independent of any one software application (such as the NextGen POS). To quote:

                                                                                                                                                                                                                                                                        [UP BOM] 是业务工作者和业务实体需要如何关联以及他们需要如何协作以执行业务的抽象。[鲁普]

                                                                                                                                                                                                                                                                        [The UP BOM] serves as an abstraction of how business workers and business entities need to be related and how they need to collaborate in order to perform the business. [RUP]

                                                                                                                                                                                                                                                                        BOM 由几个不同的图表 (类、活动和序列) 表示,这些图表说明了整个企业如何运行(或应该运行)。如果执行企业范围的业务流程工程,则它最有用,但与创建单个软件应用程序相比,这是一种不太常见的活动。

                                                                                                                                                                                                                                                                        The BOM is represented with several different diagrams (class, activity, and sequence) that illustrate how the entire enterprise runs (or should run). It is most useful if doing enterprise-wide business process engineering, but that is a less common activity than creating a single software application.

                                                                                                                                                                                                                                                                        因此,UP 将 Domain Model 定义为 BOM 的更常见创建的子集工件或专用化。引用:

                                                                                                                                                                                                                                                                        Consequently, the UP defines the Domain Model as the more commonly created subset artifact or specialization of the BOM. To quote:

                                                                                                                                                                                                                                                                        您可以选择开发一个 “不完整” 的业务对象模型,专注于解释对某个领域很重要的 “事物” 和产品。[…]这通常称为域模型。[鲁普]

                                                                                                                                                                                                                                                                        You can choose to develop an "incomplete" business object model, focusing on explaining "things" and products important to a domain. […] This is often referred to as a domain model. [RUP]

                                                                                                                                                                                                                                                                          9.20. 推荐资源

                                                                                                                                                                                                                                                                          9.20. Recommended Resources

                                                                                                                                                                                                                                                                          Odell 的 Object-Oriented Methods: A Foundation 对概念域建模进行了扎实的介绍。Cook 和 Daniel 的 Designing Object Systems 也很有用。

                                                                                                                                                                                                                                                                          Odell's Object-Oriented Methods: A Foundation provides a solid introduction to conceptual domain modeling. Cook and Daniel's Designing Object Systems is also useful.

                                                                                                                                                                                                                                                                          Fowler 的 Analysis Patterns 在域模型中提供了有价值的模式,绝对推荐使用。另一本描述领域模型中模式的好书是 Hay 的 Data Model Patterns: Conventions of Thought。数据建模专家了解纯概念模型和数据库架构模型之间的区别,他们的建议对于域对象建模非常有用。

                                                                                                                                                                                                                                                                          Fowler's Analysis Patterns offers worthwhile patterns in domain models and is definitely recommended. Another good book that describes patterns in domain models is Hay's Data Model Patterns: Conventions of Thought. Advice from data modeling experts who understand the distinction between pure conceptual models and database schema models can be very useful for domain object modeling.

                                                                                                                                                                                                                                                                          使用 UML 进行 Java Color 建模 [CDL99] 提供了比标题所暗示的更相关的域建模建议。作者确定了相关类型中的常见模式及其关联;颜色方面实际上是这些类型的常见类别的可视化,例如描述(蓝色)、角色(黄色)和时刻间隔(粉红色)。颜色用于帮助查看模式。

                                                                                                                                                                                                                                                                          Java Modeling in Color with UML [CDL99] has much more relevant domain modeling advice than the title suggests. The authors identify common patterns in related types and their associations; the color aspect is really a visualization of the common categories of these types, such as descriptions (blue), roles (yellow), and moment-intervals (pink). Color is used to aid in seeing the patterns.

                                                                                                                                                                                                                                                                            第 10 章.系统序列图

                                                                                                                                                                                                                                                                            Chapter 10. System Sequence Diagrams

                                                                                                                                                                                                                                                                            理论上和实践没有区别。但是,在实践中,确实存在。

                                                                                                                                                                                                                                                                            Jan L.A. van de Snepscheut

                                                                                                                                                                                                                                                                            In theory, there is no difference between theory and practice. But, in practice, there is.

                                                                                                                                                                                                                                                                            Jan L.A. van de Snepscheut

                                                                                                                                                                                                                                                                            目标

                                                                                                                                                                                                                                                                            Objectives

                                                                                                                                                                                                                                                                            • 识别系统事件。

                                                                                                                                                                                                                                                                            • Identify system events.

                                                                                                                                                                                                                                                                            • 为使用案例场景创建系统序列图。

                                                                                                                                                                                                                                                                            • Create system sequence diagrams for use case scenarios.



                                                                                                                                                                                                                                                                              介绍

                                                                                                                                                                                                                                                                              Introduction

                                                                                                                                                                                                                                                                              系统序列图 (SSD) 是一种快速且易于创建的工件,用于说明与所讨论的系统相关的输入和输出事件。它们是操作合同的输入,最重要的是,它们是对象设计的输入。

                                                                                                                                                                                                                                                                              A system sequence diagram (SSD) is a fast and easily created artifact that illustrates input and output events related to the systems under discussion. They are input to operation contracts andmost importantlyobject design.

                                                                                                                                                                                                                                                                              UML 包含序列图形式的表示法,用于说明从外部参与者到系统的事件。

                                                                                                                                                                                                                                                                              The UML contains notation in the form of sequence diagrams to illustrate events from external actors to a system.

                                                                                                                                                                                                                                                                              强调系统序列图的 UP 伪影影响如图 10.1 所示。使用案例文本及其隐含的系统事件将输入到 SSD 创建中。SSD 操作(例如 enterItem)反过来可以在 operation contracts 中进行分析,在 Glossary 中详细说明,最重要的是作为设计协作对象的起点。

                                                                                                                                                                                                                                                                              UP artifact influence emphasizing system sequence diagrams is shown in Figure 10.1. The use case text and its implied system events are input to SSD creation. The SSD operations (such as enterItem) can in turn be analyzed in the operation contracts, detailed in the Glossary, andmost importantserve as the starting point for designing collaborating objects.

                                                                                                                                                                                                                                                                              图 10.1.示例 UP 伪影影响。



                                                                                                                                                                                                                                                                                10.1. 示例:NextGen SSD

                                                                                                                                                                                                                                                                                10.1. Example: NextGen SSD

                                                                                                                                                                                                                                                                                对于用例中的特定事件过程,SSD 显示直接与系统交互的外部参与者、系统(作为黑盒)以及参与者生成的系统事件(参见图 10.2)。时间向下移动,事件的顺序应遵循它们在方案中的顺序。

                                                                                                                                                                                                                                                                                An SSD shows, for a particular course of events within a use case, the external actors that interact directly with the system, the system (as a black box), and the system events that the actors generate (see Figure 10.2). Time proceeds downward, and the ordering of events should follow their order in the scenario.

                                                                                                                                                                                                                                                                                图 10.2.用于流程销售场景的 SSD。



                                                                                                                                                                                                                                                                                图 10.2 示例适用于纯现金流程销售场景的主要成功场景。它指示收银员生成 makeNewSale、enterItem、endSalemakePayment 系统事件。通过阅读用例文本来暗示或建议这些事件。

                                                                                                                                                                                                                                                                                The Figure 10.2 example is for the main success scenario of a cash-only Process Sale scenario. It indicates that the cashier generates makeNewSale, enterItem, endSale, and makePayment system events. These events are implied or suggested by reading through the use case text.

                                                                                                                                                                                                                                                                                  10.2. 什么是系统序列图?

                                                                                                                                                                                                                                                                                  10.2. What are System Sequence Diagrams?

                                                                                                                                                                                                                                                                                  用例描述了外部参与者如何与我们感兴趣的软件系统进行交互。在此交互期间,参与者向系统生成系统事件,通常请求一些系统操作来处理事件。例如,当收银员输入商品的 ID 时,收银员会请求 POS 系统记录该商品的销售(enterItem 事件)。该事件在系统上启动操作。用例文本暗示enterItem 事件,而 SSD 使其具体而明确。

                                                                                                                                                                                                                                                                                  Use cases describe how external actors interact with the software system we are interested in creating. During this interaction an actor generates system events to a system, usually requesting some system operation to handle the event. For example, when a cashier enters an item's ID, the cashier is requesting the POS system to record that item's sale (the enterItem event). That event initiates an operation upon the system. The use case text implies the enterItem event, and the SSD makes it concrete and explicit.

                                                                                                                                                                                                                                                                                  UML 包括序列图作为表示法,可以说明参与者交互和它们启动的操作。

                                                                                                                                                                                                                                                                                  The UML includes sequence diagrams as a notation that can illustrate actor interactions and the operations initiated by them.

                                                                                                                                                                                                                                                                                  系统序列图是一张图片,它显示了使用案例的一个特定场景,外部参与者生成的事件、它们的顺序和系统间事件。所有系统都被视为一个黑匣子;该图的重点是跨越系统边界从 Actor 到 Systems 的事件。

                                                                                                                                                                                                                                                                                  A system sequence diagram is a picture that shows, for one particular scenario of a use case, the events that external actors generate, their order, and inter-system events. All systems are treated as a black box; the emphasis of the diagram is events that cross the system boundary from actors to systems.

                                                                                                                                                                                                                                                                                  指引

                                                                                                                                                                                                                                                                                  Guideline

                                                                                                                                                                                                                                                                                  为每个用例的主要成功场景以及频繁或复杂的替代场景绘制 SSD。

                                                                                                                                                                                                                                                                                  Draw an SSD for a main success scenario of each use case, and frequent or complex alternative scenarios.



                                                                                                                                                                                                                                                                                    10.3. 动机:为什么要绘制 SSD?

                                                                                                                                                                                                                                                                                    10.3. Motivation: Why Draw an SSD?

                                                                                                                                                                                                                                                                                    软件设计中一个有趣且有用的问题是:哪些事件会进入我们的系统?为什么?因为我们必须设计软件来处理这些事件(来自鼠标、键盘、另一个系统等)并执行响应。基本上,软件系统对三件事做出反应:1) 来自参与者(人类或计算机)的外部事件,2) 计时器事件,以及 3) 故障或异常(通常来自外部来源)。

                                                                                                                                                                                                                                                                                    An interesting and useful question in software design is this: What events are coming in to our system? Why? Because we have to design the software to handle these events (from the mouse, keyboard, another system, …) and execute a response. Basically, a software system reacts to three things: 1) external events from actors (humans or computers), 2) timer events, and 3) faults or exceptions (which are often from external sources).

                                                                                                                                                                                                                                                                                    因此,准确了解外部 input 事件 system events 是什么很有用。 它们是分析系统行为的重要组成部分。

                                                                                                                                                                                                                                                                                    Therefore, it is useful to know what, precisely, are the external input eventsthe system events. They are an important part of analyzing system behavior.

                                                                                                                                                                                                                                                                                    您可能熟悉识别进入一个软件对象的消息的概念。但是这个概念在更高级别的组件中很有用,包括(抽象地)被视为一个事物或对象的整个系统。

                                                                                                                                                                                                                                                                                    You may be familiar with the idea of identifying the messages that go into one software object. But this concept is useful at higher levels of components, including the entire system viewed (abstractly) as one thing or object.

                                                                                                                                                                                                                                                                                    在继续详细设计软件应用程序的工作原理之前,调查并将其行为定义为 “黑盒” 是很有用的。系统行为是对系统所做的事情的描述,但不解释它是如何做的。该描述的一部分是系统序列图。其他部分包括用例和系统操作协定(将在后面讨论)。

                                                                                                                                                                                                                                                                                    Before proceeding to a detailed design of how a software application will work, it is useful to investigate and define its behavior as a "black box." System behavior is a description of what a system does, without explaining how it does it. One part of that description is a system sequence diagram. Other parts include the use cases and system operation contracts (to be discussed later).

                                                                                                                                                                                                                                                                                    合同181

                                                                                                                                                                                                                                                                                    contracts p. 181



                                                                                                                                                                                                                                                                                      10.4. 应用 UML:序列图

                                                                                                                                                                                                                                                                                      10.4. Applying UML: Sequence Diagrams

                                                                                                                                                                                                                                                                                      UML 没有定义所谓的 “系统” 序列图,而只是定义 “序列图”。该限定用于强调其作为黑匣子的系统应用。稍后,序列图将在另一个上下文中使用,以说明交互软件对象的设计以完成工作。

                                                                                                                                                                                                                                                                                      The UML does not define something called a "system" sequence diagram but simply a "sequence diagram." The qualification is used to emphasize its application to systems as black boxes. Later, sequence diagrams will be used in another contextto illustrate the design of interacting software objects to fulfill work.



                                                                                                                                                                                                                                                                                      序列图中的循环

                                                                                                                                                                                                                                                                                      Loops in Sequence Diagrams

                                                                                                                                                                                                                                                                                      请注意图 10.2 中如何使用交互帧在序列图中显示循环。

                                                                                                                                                                                                                                                                                      Notice in Figure 10.2 how interaction frames are used to show loops in sequence diagrams.

                                                                                                                                                                                                                                                                                        10.5. SSD 和用例之间有什么关系?

                                                                                                                                                                                                                                                                                        10.5. What is the Relationship Between SSDs and Use Cases?

                                                                                                                                                                                                                                                                                        SSD 显示用例的一个场景的系统事件,因此它是通过检查用例生成的(参见图 10.3)。

                                                                                                                                                                                                                                                                                        An SSD shows system events for one scenario of a use case, therefore it is generated from inspection of a use case (see Figure 10.3).

                                                                                                                                                                                                                                                                                        图 10.3.SSD 源自使用案例;它们展示了一种情况。



                                                                                                                                                                                                                                                                                        应用 UML:我们应该在 SSD 中显示用例文本吗?

                                                                                                                                                                                                                                                                                        Applying UML: Should We Show Use Case Text in the SSD?

                                                                                                                                                                                                                                                                                        通常不会。如果您正确命名 SSD,则可以指示用例;例如,Process Sale Scenario

                                                                                                                                                                                                                                                                                        Not usually. If you name the SSD appropriately, you can indicate the use case; for example, Process Sale Scenario.

                                                                                                                                                                                                                                                                                          10.6. 如何命名系统事件和操作?

                                                                                                                                                                                                                                                                                          10.6. How to Name System Events and Operations?

                                                                                                                                                                                                                                                                                          scan(itemID)enterItem(itemID) 哪个更好?

                                                                                                                                                                                                                                                                                          Which is better, scan(itemID) or enterItem(itemID)?

                                                                                                                                                                                                                                                                                          系统事件应该在抽象的意图层面上表示,而不是用物理输入设备来表示。

                                                                                                                                                                                                                                                                                          System events should be expressed at the abstract level of intention rather than in terms of the physical input device.

                                                                                                                                                                                                                                                                                          因此,“enterItem” 比 “scan” (即激光扫描) 更好,因为它捕获了操作的意图,同时在关于使用什么接口来捕获系统事件的设计选择方面保持抽象和不置可否。它可以通过激光扫描仪、键盘、语音输入或任何方式。

                                                                                                                                                                                                                                                                                          Thus "enterItem" is better than "scan" (that is, laser scan) because it captures the intent of the operation while remaining abstract and noncommittal with respect to design choices about what interface is used to capture the system event. It could by via laser scanner, keyboard, voice input, or anything.

                                                                                                                                                                                                                                                                                          如图 10.4 所示,它还提高了以动词 (add..., enter..., end..., make...) 开头系统事件名称的清晰度,因为它强调这些是命令或请求。

                                                                                                                                                                                                                                                                                          It also improves clarity to start the name of a system event with a verb (add…, enter…, end…, make…), as in Figure 10.4, since it emphasizes these are commands or requests.

                                                                                                                                                                                                                                                                                          图 10.4.在抽象级别选择事件和操作名称。



                                                                                                                                                                                                                                                                                            10.7. 如何对涉及其他外部系统的 SSD 进行建模?

                                                                                                                                                                                                                                                                                            10.7. How to Model SSDs Involving Other External Systems?

                                                                                                                                                                                                                                                                                            SSD 还可用于说明系统之间的协作,例如 NextGen POS 与外部信用支付授权方之间的协作。但是,这被推迟到案例研究中的后续迭代,因为此迭代不包括远程系统协作。

                                                                                                                                                                                                                                                                                            SSDs can also be used to illustrate collaborations between systems, such as between the NextGen POS and the external credit payment authorizer. However, this is deferred until a later iteration in the case study, since this iteration does not include remote systems collaboration.

                                                                                                                                                                                                                                                                                            系统间 SSD 第 403

                                                                                                                                                                                                                                                                                            inter-system SSDs p. 403



                                                                                                                                                                                                                                                                                              10.8. 在术语表中放置哪些 SSD 信息?

                                                                                                                                                                                                                                                                                              10.8. What SSD Information to Place in the Glossary?

                                                                                                                                                                                                                                                                                              SSD 中显示的元素(操作名称、参数、返回数据)简洁明了。这些可能需要适当的解释,以便在设计过程中清楚地了解进来和出去的内容。词汇表是了解这些详细信息的好地方。

                                                                                                                                                                                                                                                                                              The elements shown in SSDs (operation name, parameters, return data) are terse. These may need proper explanation so that during design it is clear what is coming in and going out. The Glossary is a great place for these details.

                                                                                                                                                                                                                                                                                              例如,在图 10.2 中,有一行包含描述“change due, receipt”。这是对 receipta complex 报告的模糊描述。因此,UP Glossary 可以有一个收据条目,其中显示样本收据(可能是数字图片)以及详细的内容和布局。

                                                                                                                                                                                                                                                                                              For example, in Figure 10.2, there is a return line containing the description "change due, receipt." That's a vague description about the receipta complex report. So, the UP Glossary can have a receipt entry, that shows sample receipts (perhaps a digital picture), and detailed contents and layout.

                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                              通常,对于许多项目,请在 Glossary 中显示详细信息。

                                                                                                                                                                                                                                                                                              In general for many artifacts, show details in the Glossary.



                                                                                                                                                                                                                                                                                                10.9. 示例:Monopoly SSD

                                                                                                                                                                                                                                                                                                10.9. Example: Monopoly SSD

                                                                                                                                                                                                                                                                                                Play Monopoly Game 用例很简单,主要场景也是如此。观察者使用玩家数量进行初始化,然后请求模拟游戏,观察输出的轨迹,直到出现获胜者。参见图 10.5

                                                                                                                                                                                                                                                                                                The Play Monopoly Game use case is simple, as is the main scenario. The observing person initializes with the number of players, and then requests the simulation of play, watching a trace of the output until there is a winner. See Figure 10.5.

                                                                                                                                                                                                                                                                                                图 10.5.用于 Play Monopoly Game 场景的 SSD。





                                                                                                                                                                                                                                                                                                  10.10. 过程:迭代和进化 SSD

                                                                                                                                                                                                                                                                                                  10.10. Process: Iterative and Evolutionary SSDs

                                                                                                                                                                                                                                                                                                  不要为所有场景创建 SSD,除非您使用需要识别所有系统操作的估计技术(例如功能点计数)。相反,请仅为为下一次迭代选择的方案绘制这些 ID。而且,他们不应该花很长时间来素描,也许是几分钟或半小时。

                                                                                                                                                                                                                                                                                                  Don't create SSDs for all scenarios, unless you are using an estimation technique (such as function point counting) that requires identification of all system operations. Rather, draw them only for the scenarios chosen for the next iteration. And, they shouldn't take long to sketchperhaps a few minutes or a half hour.

                                                                                                                                                                                                                                                                                                  当您想了解现有系统的接口和协作,或记录架构时,SSD 也非常有用。

                                                                                                                                                                                                                                                                                                  SSDs are also very useful when you want to understand the interface and collaborations of existing systems, or to document the architecture.

                                                                                                                                                                                                                                                                                                  UP 中的 SSD

                                                                                                                                                                                                                                                                                                  SSDs Within the UP

                                                                                                                                                                                                                                                                                                  SSD 是 Use-Case Modela 的一部分,该模型是用例场景中隐含的交互的可视化。SSD 在最初的 UP 描述中没有明确提及,尽管 UP 创建者知道并理解此类图表的有用性。SSD 是 UP 或 RUP 文档未提及的许多可能的熟练且广泛使用的分析和设计工件或活动的一个例子。但 UP 非常灵活,鼓励包含任何和所有增加价值的工件和实践。

                                                                                                                                                                                                                                                                                                  SSDs are part of the Use-Case Modela visualization of the interactions implied in the scenarios of use cases. SSDs were not explicitly mentioned in the original UP description, although the UP creators are aware of and understand the usefulness of such diagrams. SSDs are an example of the many possible skillful and widely used analysis and design artifacts or activities that the UP or RUP documents do not mention. But the UP, being very flexible, encourages the inclusion of any and all artifacts and practices that add value.

                                                                                                                                                                                                                                                                                                  UP 阶段

                                                                                                                                                                                                                                                                                                  UP Phases

                                                                                                                                                                                                                                                                                                  初始SSD 通常不会在开始时被激励,除非您正在进行粗略估计(不要期望开始估计是可靠的),涉及基于识别系统操作的技术,例如功能点COCOMO II(参见 www.ifpug.org)。

                                                                                                                                                                                                                                                                                                  Inception SSDs are not usually motivated in inception, unless you are doing rough estimating (don't expect inception estimating to be reliable) involving a technique that is based on identifying system operations, such as function points or COCOMO II (see www.ifpug.org).

                                                                                                                                                                                                                                                                                                  阐述大多数 SSD 都是在制定过程中创建的,此时有助于识别系统事件的详细信息,以阐明系统必须设计处理哪些主要操作,编写系统操作合同,并可能支持估计(例如,使用未调整功能点和 COCOMO II 的宏估计)。

                                                                                                                                                                                                                                                                                                  Elaboration Most SSDs are created during elaboration, when it is useful to identify the details of the system events to clarify what major operations the system must be designed to handle, write system operation contracts, and possibly to support estimation (for example, macroestimation with unadjusted function points and COCOMO II).

                                                                                                                                                                                                                                                                                                    10.11. 历史和推荐资源

                                                                                                                                                                                                                                                                                                    10.11. History and Recommended Resources

                                                                                                                                                                                                                                                                                                    识别软件系统的公共操作是一项非常古老的需求,因此,用于说明被视为黑匣子的系统的 I/O 事件的系统接口图的变体已经广泛使用了几十年。例如,在电信中,它们被称为呼叫流图。它们首先在 Fusion 方法 [Coleman+94] 的 OO 方法中得到普及,该方法提供了 SSD 和系统操作与其他分析和设计工件的关系的详细示例。

                                                                                                                                                                                                                                                                                                    Identifying a software system's public operations is a very old need, so variations of system interface diagrams that illustrate the I/O events for a system treated as a black box have been in widespread use for many decades. For example, in telecommunications they have been called call-flow diagrams. They were first popularized in OO methods in the Fusion method [Coleman+94], which provided a detailed example of the relationship of SSDs and system operations to other analysis and design artifacts.

                                                                                                                                                                                                                                                                                                      第 11 章.运营合同

                                                                                                                                                                                                                                                                                                      Chapter 11. Operation Contracts

                                                                                                                                                                                                                                                                                                      当想法失败时,文字会派上用场。

                                                                                                                                                                                                                                                                                                      约翰·沃尔夫冈·冯·歌德

                                                                                                                                                                                                                                                                                                      When ideas fail, words come in very handy.

                                                                                                                                                                                                                                                                                                      Johann Wolfgang von Goethe

                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                      • 定义系统操作。

                                                                                                                                                                                                                                                                                                      • Define system operations.

                                                                                                                                                                                                                                                                                                      • 为系统操作创建合同。

                                                                                                                                                                                                                                                                                                      • Create contracts for system operations.



                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                        用例或系统功能是 UP 中描述系统行为的主要方式,通常就足够了。有时,对系统行为的更详细或精确的描述是有价值的。操作协定使用前提条件和后提条件形式来描述系统操作对域模型中对象的详细更改。域模型是最常见的 OOA 模型,但操作 Contract 和状态模型(第 485 页介绍)也可以是有用的 OOA 相关工件。

                                                                                                                                                                                                                                                                                                        Use cases or system features are the main ways in the UP to describe system behavior, and are usually sufficient. Sometimes a more detailed or precise description of system behavior has value. Operation contracts use a pre- and post-condition form to describe detailed changes to objects in a domain model, as the result of a system operation. A domain model is the most common OOA model, but operation contracts and state models (introduced on p. 485) can also be useful OOA-related artifacts.

                                                                                                                                                                                                                                                                                                        运营合同可以被视为 UP 用例模型的一部分,因为它们提供了有关用例中隐含的系统操作效果的更多分析细节。

                                                                                                                                                                                                                                                                                                        Operation contracts may be considered part of the UP Use-Case Model because they provide more analysis detail on the effect of the system operations implied in the use cases.

                                                                                                                                                                                                                                                                                                        强调操作合约的 UP artifact influence 如图 11.1 所示。合约的主要输入是在 SSD 中标识的系统操作(例如 enterItem)、域模型和专家的域见解。这些 Contract 反过来可以用作对象设计的输入,因为它们描述了软件对象或数据库中可能需要的更改。

                                                                                                                                                                                                                                                                                                        UP artifact influence emphasizing operation contracts is shown in Figure 11.1. The prime inputs to the contracts are the system operations identified in SSDs (such as enterItem), the domain model, and domain insight from experts. The contracts can in turn serve as input to the object design, as they describe changes that are likely required in the software objects or database.

                                                                                                                                                                                                                                                                                                        图 11.1.示例 UP 伪影影响。



                                                                                                                                                                                                                                                                                                          11.1. 示例

                                                                                                                                                                                                                                                                                                          11.1. Example

                                                                                                                                                                                                                                                                                                          下面是 enterItem 系统操作的操作协定。关键元素是后置条件;其他部分有用但不太重要。

                                                                                                                                                                                                                                                                                                          Here's an operation contract for the enterItem system operation. The critical element is the postconditions; the other parts are useful but less important.

                                                                                                                                                                                                                                                                                                          CO2 合同:enterItem

                                                                                                                                                                                                                                                                                                          操作:

                                                                                                                                                                                                                                                                                                          Operation:

                                                                                                                                                                                                                                                                                                          enterItem(itemID: 商品 ID, 数量: 整数)

                                                                                                                                                                                                                                                                                                          enterItem(itemID: ItemID, quantity: integer)

                                                                                                                                                                                                                                                                                                          交叉引用:

                                                                                                                                                                                                                                                                                                          Cross References:

                                                                                                                                                                                                                                                                                                          使用案例:流程销售

                                                                                                                                                                                                                                                                                                          Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                          前提 条件:

                                                                                                                                                                                                                                                                                                          Preconditions:

                                                                                                                                                                                                                                                                                                          正在进行促销活动。

                                                                                                                                                                                                                                                                                                          There is a sale underway.

                                                                                                                                                                                                                                                                                                          后置条件:

                                                                                                                                                                                                                                                                                                          Postconditions:

                                                                                                                                                                                                                                                                                                          - 已创建 SalesLineItem 实例 sli (实例创建)。

                                                                                                                                                                                                                                                                                                          - A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                          - sli 与当前的 Sale 相关联(已形成协会)。

                                                                                                                                                                                                                                                                                                          - sli was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                          - sli.quantity 变为 quantity (属性修改)。

                                                                                                                                                                                                                                                                                                          - sli.quantity became quantity (attribute modification).

                                                                                                                                                                                                                                                                                                          - sli 根据 itemID 匹配(形成关联)与 ProductDescription 关联。

                                                                                                                                                                                                                                                                                                          - sli was associated with a ProductDescription, based on itemID match (association formed).



                                                                                                                                                                                                                                                                                                          诸如 “(实例创建)” 之类的分类是一种学习辅助工具,不是合同的适当组成部分。

                                                                                                                                                                                                                                                                                                          The categorizations such as "(instance creation)" are a learning aid, not properly part of the contract.

                                                                                                                                                                                                                                                                                                            11.2. 定义:合同的条款是什么?

                                                                                                                                                                                                                                                                                                            11.2. Definition: What are the Sections of a Contract?

                                                                                                                                                                                                                                                                                                            以下架构显示了协定中每个部分的描述。

                                                                                                                                                                                                                                                                                                            A description of each section in a contract is shown in the following schema.

                                                                                                                                                                                                                                                                                                            操作:

                                                                                                                                                                                                                                                                                                            Operation:

                                                                                                                                                                                                                                                                                                            操作名称和参数

                                                                                                                                                                                                                                                                                                            Name of operation, and parameters

                                                                                                                                                                                                                                                                                                            交叉引用:

                                                                                                                                                                                                                                                                                                            Cross References:

                                                                                                                                                                                                                                                                                                            此操作可能发生在

                                                                                                                                                                                                                                                                                                            Use cases this operation can occur within

                                                                                                                                                                                                                                                                                                            前提 条件:

                                                                                                                                                                                                                                                                                                            Preconditions:

                                                                                                                                                                                                                                                                                                            在执行操作之前,关于系统或域模型中对象状态的值得注意的假设。这些是应该告诉读者的重要假设。

                                                                                                                                                                                                                                                                                                            Noteworthy assumptions about the state of the system or objects in the Domain Model before execution of the operation. These are non-trivial assumptions the reader should be told.

                                                                                                                                                                                                                                                                                                            后置条件:

                                                                                                                                                                                                                                                                                                            Postconditions:

                                                                                                                                                                                                                                                                                                            这是最重要的部分。操作完成后 Domain Model 中对象的状态。将在下一节中详细讨论。

                                                                                                                                                                                                                                                                                                            This is the most important section. The state of objects in the Domain Model after completion of the operation. Discussed in detail in a following section.



                                                                                                                                                                                                                                                                                                              11.3. 定义:什么是系统操作?

                                                                                                                                                                                                                                                                                                              11.3. Definition: What is a System Operation?

                                                                                                                                                                                                                                                                                                              可以为系统操作定义操作协定,系统作为黑盒组件在其公共接口中提供这些操作。在绘制 SSD 草图时可以识别系统操作,如图 11.2 所示。更准确地说,SSD 显示与系统相关的系统事件、事件或 I/O 消息。输入系统事件意味着系统具有处理事件的系统操作,就像 OO 消息(一种事件或信号)由 OO 方法(一种操作)处理一样。

                                                                                                                                                                                                                                                                                                              Operation contracts may be defined for system operationsoperations that the system as a black box component offers in its public interface. System operations can be identified while sketching SSDs, as in Figure 11.2. To be more precise, the SSDs show system eventsevents or I/O messages relative to the system. Input system events imply the system has system operations to handle the events, just as an OO message (a kind of event or signal) is handled by an OO method (a kind of operation).

                                                                                                                                                                                                                                                                                                              图 11.2.SSD 的。系统操作处理输入系统事件。



                                                                                                                                                                                                                                                                                                              在所有用例中,整个系统操作集定义了公共系统接口,将系统视为单个组件或类。在 UML 中,整个系统可以表示为名为 (例如) System 的类的一个对象。

                                                                                                                                                                                                                                                                                                              The entire set of system operations, across all use cases, defines the public system interface, viewing the system as a single component or class. In the UML, the system as a whole can be represented as one object of a class named (for example) System.

                                                                                                                                                                                                                                                                                                                11.4. 定义:后置条件

                                                                                                                                                                                                                                                                                                                11.4. Definition: Postconditions

                                                                                                                                                                                                                                                                                                                请注意,enterItem 示例中的每个后置条件都包含一个学习辅助分类,例如实例创建已形成关联。这里有一个关键点:

                                                                                                                                                                                                                                                                                                                Notice that each of the postconditions in the enterItem example included a learning aid categorization such as instance creation or association formed. Here is a key point:

                                                                                                                                                                                                                                                                                                                定义

                                                                                                                                                                                                                                                                                                                Definition

                                                                                                                                                                                                                                                                                                                后置条件描述域模型中对象状态的变化。域模型状态更改包括创建的实例、形成或断开的关联以及属性更改。

                                                                                                                                                                                                                                                                                                                The postconditions describe changes in the state of objects in the domain model. Domain model state changes include instances created, associations formed or broken, and attributes changed.



                                                                                                                                                                                                                                                                                                                后置条件不是在操作期间要执行的操作;相反,它们是对域模型对象的观察结果,当烟雾散去后操作完成时,这些对象为 true。

                                                                                                                                                                                                                                                                                                                Postconditions are not actions to be performed during the operation; rather, they are observations about the domain model objects that are true when the operation has finishedafter the smoke has cleared.

                                                                                                                                                                                                                                                                                                                总而言之,后置条件分为以下几类:

                                                                                                                                                                                                                                                                                                                To summarize, the postconditions fall into these categories:

                                                                                                                                                                                                                                                                                                                • 实例创建和删除。

                                                                                                                                                                                                                                                                                                                • Instance creation and deletion.

                                                                                                                                                                                                                                                                                                                • 值的属性更改。

                                                                                                                                                                                                                                                                                                                • Attribute change of value.

                                                                                                                                                                                                                                                                                                                • 关联(准确地说,UML 链接)形成和断开。

                                                                                                                                                                                                                                                                                                                • Associations (to be precise, UML links) formed and broken.



                                                                                                                                                                                                                                                                                                                打破关联的情况很少见。但例如,请考虑允许删除行项目的操作。后置条件可以读取“所选 SalesLineItemSale 的关联已断开”。在其他领域,当贷款还清或有人取消他们在某件事中的会员资格时,协会就会被打破。

                                                                                                                                                                                                                                                                                                                Breaking associations is rare. But as an example, consider an operation to allow the deletion of line items. The postcondition could read "The selected SalesLineItem's association with the Sale was broken." In other domains, when a loan is paid off or someone cancels their membership in something, associations are broken.

                                                                                                                                                                                                                                                                                                                实例删除后置条件是最罕见的,因为人们通常不关心在现实世界中明确强制执行事物的销毁。例如:在许多国家/地区,一个人宣布破产后,七年或十年过去了,必须依法销毁其破产宣布的所有记录。请注意,这是一个概念角度,而不是实现。这些不是关于释放软件对象占用的计算机中的内存的陈述。

                                                                                                                                                                                                                                                                                                                Instance deletion postconditions are most rare, because one does not usually care about explicitly enforcing the destruction of a thing in the real world. As an example: In many countries, after a person has declared bankruptcy and seven or ten years have passed, all records of their bankruptcy declaration must be destroyed, by law. Note that this is a conceptual perspective, not implementation. These are not statements about freeing up memory in a computer occupied by software objects.

                                                                                                                                                                                                                                                                                                                后置条件与域模型有什么关系?

                                                                                                                                                                                                                                                                                                                How are Postconditions Related to the Domain Model?

                                                                                                                                                                                                                                                                                                                这些后置条件在 Domain Model 对象的上下文中表示。可以创建哪些实例?来自域模型的实例;可以形成哪些关联?域模型中的关联;等等。

                                                                                                                                                                                                                                                                                                                These postconditions are expressed in the context of the Domain Model objects. What instances can be created?those from the Domain Model; What associations can be formed?those in the Domain Model; and so on.

                                                                                                                                                                                                                                                                                                                动机:为什么是后条件?

                                                                                                                                                                                                                                                                                                                Motivation: Why Postconditions?

                                                                                                                                                                                                                                                                                                                首先,它们并不总是必要的。大多数情况下,通过阅读用例、与专家交谈或他们自己的知识,开发人员相对清楚系统操作的效果。但有时更多的细节和精度是有用的。合同提供了这一点。

                                                                                                                                                                                                                                                                                                                First, they aren't always necessary. Most often, the effect of a system operation is relatively clear to the developers by virtue of reading the use case, talking with experts, or their own knowledge. But sometimes more detail and precision is useful. Contracts offer that.

                                                                                                                                                                                                                                                                                                                请注意,后置条件支持在声明操作结果必须是什么时的细粒度和精度。也可以在用例中表达这种详细程度,但不希望它们过于冗长且细节级别较低。

                                                                                                                                                                                                                                                                                                                Notice that the postconditions support fine-grained detail and precision in declaring what the outcome of the operation must be. It is also possible to express this level of detail in the use cases, but undesirablethey would be too verbose and low-level detailed.

                                                                                                                                                                                                                                                                                                                契约是需求分析或 OOA 的优秀工具,它非常详细地描述了系统操作所需的更改(就领域模型对象而言),而不必描述如何实现它们。

                                                                                                                                                                                                                                                                                                                A contract is an excellent tool of requirements analysis or OOA that describes in great detail the changes required by a system operation (in terms of the domain model objects) without having to describe how they are to be achieved.

                                                                                                                                                                                                                                                                                                                换句话说,设计可以推迟,我们可以专注于分析必须发生的事情,而不是如何完成它。

                                                                                                                                                                                                                                                                                                                In other words, the design can be deferred, and we can focus on the analysis of what must happen, rather than how it is to be accomplished.

                                                                                                                                                                                                                                                                                                                考虑这些后置条件:

                                                                                                                                                                                                                                                                                                                Consider these postconditions:

                                                                                                                                                                                                                                                                                                                后置条件:

                                                                                                                                                                                                                                                                                                                Postconditions:

                                                                                                                                                                                                                                                                                                                - 已创建 SalesLineItem 实例 sli (实例创建)。

                                                                                                                                                                                                                                                                                                                - A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                                - sli 与当前销售相关联(已形成关联)。

                                                                                                                                                                                                                                                                                                                - sli was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                - sli.quantity 变为 quantity (属性修改)。

                                                                                                                                                                                                                                                                                                                - sli.quantity became quantity (attribute modification).

                                                                                                                                                                                                                                                                                                                - sli 根据 itemID 匹配(形成关联)与 ProductDescription 关联。

                                                                                                                                                                                                                                                                                                                - sli was associated with a ProductDescription, based on itemID match (association formed).



                                                                                                                                                                                                                                                                                                                没有关于如何创建 SalesLineItem 实例或如何与 Sale 关联的注释。这可能是关于在纸片上书写并将它们装订在一起、使用 Java 技术创建软件对象并连接它们或在关系数据库中插入行的声明。

                                                                                                                                                                                                                                                                                                                No comment is made about how a SalesLineItem instance is created, or associated with a Sale. This could be a statement about writing on bits of paper and stapling them together, using Java technologies to create software objects and connect them, or inserting rows in a relational database.

                                                                                                                                                                                                                                                                                                                指南:如何编写后置条件?

                                                                                                                                                                                                                                                                                                                Guideline: How to Write a Postcondition?

                                                                                                                                                                                                                                                                                                                用过去时表示后置条件,以强调它们是对操作引起的状态变化的观察,而不是要发生的操作。这就是为什么它们被称为 postconditions!例如:

                                                                                                                                                                                                                                                                                                                Express postconditions in the past tense to emphasize they are observations about state changes that arose from an operation, not an action to happen. That's why they are called postconditions! For example:

                                                                                                                                                                                                                                                                                                                • (更好)创建 SalesLineItem

                                                                                                                                                                                                                                                                                                                • (better) A SalesLineItem was created.

                                                                                                                                                                                                                                                                                                                而不是

                                                                                                                                                                                                                                                                                                                rather than

                                                                                                                                                                                                                                                                                                                • (更糟)创建 SalesLineItem,或者创建 SalesLineItem

                                                                                                                                                                                                                                                                                                                • (worse) Create a SalesLineItem, or, A SalesLineItem is created.

                                                                                                                                                                                                                                                                                                                类比:后条件的精神:舞台和幕布

                                                                                                                                                                                                                                                                                                                Analogy: The Spirit of Postconditions: The Stage and Curtain

                                                                                                                                                                                                                                                                                                                为什么要用过去时写 postconditions?使用下图来考虑它们:

                                                                                                                                                                                                                                                                                                                Why write postconditions in the past tense? Think about them using the following image:

                                                                                                                                                                                                                                                                                                                该系统及其对象在剧院舞台上呈现。

                                                                                                                                                                                                                                                                                                                The system and its objects are presented on a theatre stage.

                                                                                                                                                                                                                                                                                                                1.
                                                                                                                                                                                                                                                                                                                手术前,拍一张舞台的照片。



                                                                                                                                                                                                                                                                                                                2.
                                                                                                                                                                                                                                                                                                                拉上舞台上的窗帘,然后应用系统操作(叮当声、尖叫声和尖叫声等背景噪音......



                                                                                                                                                                                                                                                                                                                3.
                                                                                                                                                                                                                                                                                                                拉开窗帘,拍第二张照片。



                                                                                                                                                                                                                                                                                                                4.
                                                                                                                                                                                                                                                                                                                比较之前和之后的图片,并将舞台状态的变化表示为后置条件(创建了 SalesLineItem...



                                                                                                                                                                                                                                                                                                                指南:后置条件应该有多完整?敏捷分析与繁重分析

                                                                                                                                                                                                                                                                                                                Guideline: How Complete Should Postconditions Be? Agile vs. Heavy Analysis

                                                                                                                                                                                                                                                                                                                合同可能没有用。此问题将在后续部分中讨论。但是假设有些是有用的,那么为所有系统操作生成一组完整而详细的后置条件不太可能也没有必要。本着敏捷建模的精神,将它们的创建视为初始的最佳猜测,并理解它们不会完整,并且“完美”的完整规范很少可能或可信。

                                                                                                                                                                                                                                                                                                                Contracts may not be useful. This question is discussed in a subsequent section. But assuming some are useful, generating a complete and detailed set of postconditions for all system operations is not likelyor necessary. In the spirit of Agile Modeling, treat their creation as an initial best guess, with the understanding they will not be complete and that "perfect" complete specifications are rarely possible or believable.

                                                                                                                                                                                                                                                                                                                但是,理解轻分析是现实和熟练的并不意味着在编程之前放弃一点调查这是误解的另一个极端。

                                                                                                                                                                                                                                                                                                                But understanding that light analysis is realistic and skillful doesn't mean to abandon a little investigation before programmingthat's the other extreme of misunderstanding.

                                                                                                                                                                                                                                                                                                                  11.5. 示例:enterItem 后置条件

                                                                                                                                                                                                                                                                                                                  11.5. Example: enterItem Postconditions

                                                                                                                                                                                                                                                                                                                  以下部分剖析了 enterItem 系统操作的后置条件的动机。

                                                                                                                                                                                                                                                                                                                  The following section dissects the motivation for the postconditions of the enterItem system operation.

                                                                                                                                                                                                                                                                                                                  实例创建和删除

                                                                                                                                                                                                                                                                                                                  Instance Creation and Deletion

                                                                                                                                                                                                                                                                                                                  输入商品的 itemID数量后,应该创建什么新对象?一个 SalesLineItem。因此:

                                                                                                                                                                                                                                                                                                                  After the itemID and quantity of an item have been entered, what new object should have been created? A SalesLineItem. Thus:

                                                                                                                                                                                                                                                                                                                  • 已创建 SalesLineItem 实例 sli(实例创建)。

                                                                                                                                                                                                                                                                                                                  • A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                                  记下实例的命名。此名称将简化其他后置条件语句中对新实例的引用。

                                                                                                                                                                                                                                                                                                                  Note the naming of the instance. This name will simplify references to the new instance in other post-condition statements.

                                                                                                                                                                                                                                                                                                                  属性修改

                                                                                                                                                                                                                                                                                                                  Attribute Modification

                                                                                                                                                                                                                                                                                                                  收银员输入商品的 itemID 和数量后,应该修改新对象的或现有对象的哪些属性?SalesLineItem 的数量应等于 quantity 参数。因此:

                                                                                                                                                                                                                                                                                                                  After the itemID and quantity of an item have been entered by the cashier, what attributes of new or existing objects should have been modified? The quantity of the SalesLineItem should have become equal to the quantity parameter. Thus:

                                                                                                                                                                                                                                                                                                                  • sli.quantity 变为 quantity (属性修改)。

                                                                                                                                                                                                                                                                                                                  • sli.quantity became quantity (attribute modification).

                                                                                                                                                                                                                                                                                                                  协会的形成和破坏

                                                                                                                                                                                                                                                                                                                  Associations Formed and Broken

                                                                                                                                                                                                                                                                                                                  在收银员输入商品的 itemID数量后,新对象或现有对象之间应该形成或断开哪些关联?新的 SalesLineItem 应该已经与其 Sale 相关,并且与其 ProductDescription 相关。因此:

                                                                                                                                                                                                                                                                                                                  After the itemID and quantity of an item have been entered by the cashier, what associations between new or existing objects should have been formed or broken? The new SalesLineItem should have been related to its Sale, and related to its ProductDescription. Thus:

                                                                                                                                                                                                                                                                                                                  • sli 与当前的 Sale 相关联(已形成协会)。

                                                                                                                                                                                                                                                                                                                  • sli was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                  • sli 根据 itemID 匹配(形成关联)与 ProductDescription 关联。

                                                                                                                                                                                                                                                                                                                  • sli was associated with a ProductDescription, based on itemID match (association formed).

                                                                                                                                                                                                                                                                                                                  请注意,非正式指示表明它与 itemID 与参数匹配的 ProductDescription形成关系。可以使用更花哨和正式的语言方法,例如使用对象约束语言 (OCL)。建议:保持简单明了。

                                                                                                                                                                                                                                                                                                                  Note the informal indication that it forms a relationship with a ProductDescriptionthe one whose itemID matches the parameter. More fancy and formal language approaches are possible, such as using the Object Constraint Language (OCL). Recommendation: Keep it plain and simple.

                                                                                                                                                                                                                                                                                                                    11.6. 指南:我们应该更新域模型吗?

                                                                                                                                                                                                                                                                                                                    11.6. Guideline: Should We Update the Domain Model?

                                                                                                                                                                                                                                                                                                                    在创建协定期间,通常会发现需要在域模型中记录新的概念类、属性或关联。不要局限于域模型的先前定义;当您在考虑运营合同时获得新发现时增强它。

                                                                                                                                                                                                                                                                                                                    It's common during the creation of the contracts to discover the need to record new conceptual classes, attributes, or associations in the domain model. Do not be limited to the prior definition of the domain model; enhance it as you make new discoveries while thinking through operation contracts.

                                                                                                                                                                                                                                                                                                                    在迭代和进化方法(并反映软件项目的现实)中,所有分析和设计工件都被认为是部分和不完美的,并且会随着新发现而发展。

                                                                                                                                                                                                                                                                                                                    In iterative and evolutionary methods (and reflecting the reality of software projects), all analysis and design artifacts are considered partial and imperfect, and evolve in response to new discoveries.



                                                                                                                                                                                                                                                                                                                      11.7. 指南:合约何时有用?

                                                                                                                                                                                                                                                                                                                      11.7. Guideline: When Are Contracts Useful?

                                                                                                                                                                                                                                                                                                                      在 UP 中,用例是项目需求的主要存储库。它们可能会提供了解设计中该做什么所需的大部分或全部细节,在这种情况下,合同没有帮助。但是,在某些情况下,所需状态更改的细节和复杂性很尴尬,或者太详细而无法在用例中捕获。

                                                                                                                                                                                                                                                                                                                      In the UP, the use cases are the main repository of requirements for the project. They may provide most or all of the detail necessary to know what to do in the design, in which case, contracts are not helpful. However, there are situations where the details and complexity of required state changes are awkward or too detailed to capture in use cases.

                                                                                                                                                                                                                                                                                                                      例如,考虑一个航空公司预订系统和系统操作 addNewReservation。对于必须更改、创建和关联的所有域对象,复杂性非常高。这些细粒度的细节可以在用例中写下来,但它会使其非常详细(例如,注意所有必须更改的对象中的每个属性)。

                                                                                                                                                                                                                                                                                                                      For example, consider an airline reservation system and the system operation addNewReservation. The complexity is very high regarding all the domain objects that must be changed, created, and associated. These fine-grained details can be written up in the use case, but it will make it extremely detailed (for example, noting each attribute in all the objects that must change).

                                                                                                                                                                                                                                                                                                                      请注意,后置条件格式提供并鼓励一种非常精确的分析语言,该语言支持详细的彻底性。

                                                                                                                                                                                                                                                                                                                      Observe that the postcondition format offers and encourages a very precise, analytical language that supports detailed thoroughness.

                                                                                                                                                                                                                                                                                                                      如果开发人员可以轻松理解没有它们该怎么办,那么请避免编写 Contract。

                                                                                                                                                                                                                                                                                                                      If developers can comfortably understand what to do without them, then avoid writing contracts.

                                                                                                                                                                                                                                                                                                                      本案例研究显示,合同数量超过了教育所需的合同数量。在实践中,它们记录的大部分细节显然可以从用例文本中推断出来。另一方面,“显而易见”是一个狡猾的概念!

                                                                                                                                                                                                                                                                                                                      This case study shows more contracts than are necessaryfor education. In practice, most of the details they record are obviously inferable from the use case text. On the other hand, "obvious" is a slippery concept!

                                                                                                                                                                                                                                                                                                                        11.8. 指南:如何创建和编写 Contract

                                                                                                                                                                                                                                                                                                                        11.8. Guideline: How to Create and Write Contracts

                                                                                                                                                                                                                                                                                                                        应用以下建议来创建合同:

                                                                                                                                                                                                                                                                                                                        Apply the following advice to create contracts:

                                                                                                                                                                                                                                                                                                                        1. 识别 SSD 中的系统操作。

                                                                                                                                                                                                                                                                                                                        2. Identify system operations from the SSDs.

                                                                                                                                                                                                                                                                                                                        3. 对于复杂且结果可能微妙的系统操作,或者在用例中不清楚的系统操作,请构建合约。

                                                                                                                                                                                                                                                                                                                        4. For system operations that are complex and perhaps subtle in their results, or which are not clear in the use case, construct a contract.

                                                                                                                                                                                                                                                                                                                        5. 要描述 postcondition,请使用以下类别:

                                                                                                                                                                                                                                                                                                                          • 实例创建和删除

                                                                                                                                                                                                                                                                                                                          • 属性修改

                                                                                                                                                                                                                                                                                                                          • 关联形成和中断

                                                                                                                                                                                                                                                                                                                        6. To describe the postconditions, use the following categories:

                                                                                                                                                                                                                                                                                                                          • instance creation and deletion

                                                                                                                                                                                                                                                                                                                          • attribute modification

                                                                                                                                                                                                                                                                                                                          • associations formed and broken

                                                                                                                                                                                                                                                                                                                        编写合同

                                                                                                                                                                                                                                                                                                                        Writing Contracts

                                                                                                                                                                                                                                                                                                                        • 如前所述,将后置条件写成陈述性的、被动的过去时形式 (was ...) 以强调对变化的观察,而不是如何实现变化的设计。例如:

                                                                                                                                                                                                                                                                                                                          • (更好)创建 SalesLineItem

                                                                                                                                                                                                                                                                                                                          • (更糟)创建 SalesLineItem

                                                                                                                                                                                                                                                                                                                        • As mentioned, write the postconditions in a declarative, passive past tense form (was …) to emphasize the observation of a change rather than a design of how it is going to be achieved. For example:

                                                                                                                                                                                                                                                                                                                          • (better) A SalesLineItem was created.

                                                                                                                                                                                                                                                                                                                          • (worse) Create a SalesLineItem.

                                                                                                                                                                                                                                                                                                                        • 请记住在现有对象或新创建的对象之间建立关联。例如,在执行 enterItem 操作时创建新的 SalesLineItem 实例是不够的。操作完成后,新创建的实例与 Sale 关联也应该是真的;因此:

                                                                                                                                                                                                                                                                                                                          • SalesLineItemSale 关联(形成关联)。

                                                                                                                                                                                                                                                                                                                        • Remember to establish an association between existing objects or those newly created. For example, it is not enough that a new SalesLineItem instance is created when the enterItem operation occurs. After the operation is complete, it should also be true that the newly created instance was associated with Sale; thus:

                                                                                                                                                                                                                                                                                                                          • The SalesLineItem was associated with the Sale (association formed).

                                                                                                                                                                                                                                                                                                                        最常见的错误是什么?

                                                                                                                                                                                                                                                                                                                        What's the Most Common Mistake?

                                                                                                                                                                                                                                                                                                                        最常见的问题是忘记包括协会的形成。特别是在创建新实例时,很可能需要建立与多个对象的关联。别忘了!

                                                                                                                                                                                                                                                                                                                        The most common problem is forgetting to include the forming of associations. Particularly when new instances are created, it is very likely that associations to several objects need be established. Don't forget!

                                                                                                                                                                                                                                                                                                                          11.9. 示例:NextGen POS 合同

                                                                                                                                                                                                                                                                                                                          11.9. Example: NextGen POS Contracts

                                                                                                                                                                                                                                                                                                                          Process Sales 使用案例的系统操作

                                                                                                                                                                                                                                                                                                                          System Operations of the Process Sale Use Case

                                                                                                                                                                                                                                                                                                                          CO1 合约:makeNewSale

                                                                                                                                                                                                                                                                                                                          操作:

                                                                                                                                                                                                                                                                                                                          Operation:

                                                                                                                                                                                                                                                                                                                          makeNewSale()

                                                                                                                                                                                                                                                                                                                          makeNewSale()

                                                                                                                                                                                                                                                                                                                          交叉引用:

                                                                                                                                                                                                                                                                                                                          Cross References:

                                                                                                                                                                                                                                                                                                                          使用案例:流程销售

                                                                                                                                                                                                                                                                                                                          Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                          前提 条件:

                                                                                                                                                                                                                                                                                                                          Preconditions:

                                                                                                                                                                                                                                                                                                                          没有

                                                                                                                                                                                                                                                                                                                          none

                                                                                                                                                                                                                                                                                                                          后置条件:

                                                                                                                                                                                                                                                                                                                          Postconditions:

                                                                                                                                                                                                                                                                                                                          - 已创建 Sale 实例 (实例创建)。

                                                                                                                                                                                                                                                                                                                          - A Sale instance s was created (instance creation).

                                                                                                                                                                                                                                                                                                                          - s 与一个 Register 相关联(association formed )。

                                                                                                                                                                                                                                                                                                                          - s was associated with a Register (association formed).

                                                                                                                                                                                                                                                                                                                          - 初始化 s 的属性。

                                                                                                                                                                                                                                                                                                                          - Attributes of s were initialized.



                                                                                                                                                                                                                                                                                                                          请注意最后一个 postcondition 中模糊的描述。如果可以理解,那就没问题。

                                                                                                                                                                                                                                                                                                                          Note the vague description in the last postcondition. If understandable, it's fine.

                                                                                                                                                                                                                                                                                                                          在一个项目中,所有这些特定的后置条件从用例中都是如此明显,以至于可能不应该编写 makeNewSale 契约。

                                                                                                                                                                                                                                                                                                                          On a project, all these particular postconditions are so obvious from the use case that the makeNewSale contract should probably not be written.

                                                                                                                                                                                                                                                                                                                          回想一下健康过程和 UP 的指导原则之一:尽可能保持轻松,避免所有伪影,除非它们真的增加了价值。

                                                                                                                                                                                                                                                                                                                          Recall one of the guiding principles of healthy process and the UP: Keep it as light as possible, and avoid all artifacts unless they really add value.

                                                                                                                                                                                                                                                                                                                          CO2 合同:enterItem

                                                                                                                                                                                                                                                                                                                          操作:

                                                                                                                                                                                                                                                                                                                          Operation:

                                                                                                                                                                                                                                                                                                                          enterItem(itemID: 商品 ID, 数量: 整数)

                                                                                                                                                                                                                                                                                                                          enterItem(itemID: ItemID, quantity: integer)

                                                                                                                                                                                                                                                                                                                          交叉引用:

                                                                                                                                                                                                                                                                                                                          Cross References:

                                                                                                                                                                                                                                                                                                                          使用案例:流程销售

                                                                                                                                                                                                                                                                                                                          Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                          前提 条件:

                                                                                                                                                                                                                                                                                                                          Preconditions:

                                                                                                                                                                                                                                                                                                                          正在进行促销活动。

                                                                                                                                                                                                                                                                                                                          There is a sale underway.

                                                                                                                                                                                                                                                                                                                          后置条件:

                                                                                                                                                                                                                                                                                                                          Postconditions:

                                                                                                                                                                                                                                                                                                                          - 已创建 SalesLineItem 实例 sli (实例创建)。

                                                                                                                                                                                                                                                                                                                          - A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                                          - sli 与当前销售相关联(已形成关联)。

                                                                                                                                                                                                                                                                                                                          - sli was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                          - sli.quantity 变为 quantity (属性修改)。

                                                                                                                                                                                                                                                                                                                          - sli.quantity became quantity (attribute modification).

                                                                                                                                                                                                                                                                                                                          - sli 根据 itemID 匹配(形成关联)与 ProductDescription 关联。

                                                                                                                                                                                                                                                                                                                          - sli was associated with a ProductDescription, based on itemID match (association formed).



                                                                                                                                                                                                                                                                                                                          CO3 合同:endSale

                                                                                                                                                                                                                                                                                                                          操作:

                                                                                                                                                                                                                                                                                                                          Operation:

                                                                                                                                                                                                                                                                                                                          endSale()

                                                                                                                                                                                                                                                                                                                          endSale()

                                                                                                                                                                                                                                                                                                                          交叉引用:

                                                                                                                                                                                                                                                                                                                          Cross References:

                                                                                                                                                                                                                                                                                                                          使用案例:流程销售

                                                                                                                                                                                                                                                                                                                          Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                          前提 条件:

                                                                                                                                                                                                                                                                                                                          Preconditions:

                                                                                                                                                                                                                                                                                                                          正在进行促销活动。

                                                                                                                                                                                                                                                                                                                          There is a sale underway.

                                                                                                                                                                                                                                                                                                                          后置条件:

                                                                                                                                                                                                                                                                                                                          Postconditions:

                                                                                                                                                                                                                                                                                                                          - Sale.isComplete 变为 true(属性修改)。

                                                                                                                                                                                                                                                                                                                          - Sale.isComplete became true (attribute modification).



                                                                                                                                                                                                                                                                                                                          CO4 合同:makePayment

                                                                                                                                                                                                                                                                                                                          操作:

                                                                                                                                                                                                                                                                                                                          Operation:

                                                                                                                                                                                                                                                                                                                          makePayment( 金额 : 钱 )

                                                                                                                                                                                                                                                                                                                          makePayment( amount: Money )

                                                                                                                                                                                                                                                                                                                          交叉引用:

                                                                                                                                                                                                                                                                                                                          Cross References:

                                                                                                                                                                                                                                                                                                                          使用案例:流程销售

                                                                                                                                                                                                                                                                                                                          Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                          前提 条件:

                                                                                                                                                                                                                                                                                                                          Preconditions:

                                                                                                                                                                                                                                                                                                                          正在进行促销活动。

                                                                                                                                                                                                                                                                                                                          There is a sale underway.

                                                                                                                                                                                                                                                                                                                          后置条件:

                                                                                                                                                                                                                                                                                                                          Postconditions:

                                                                                                                                                                                                                                                                                                                          - 创建了一个 Payment 实例 p(实例创建)。

                                                                                                                                                                                                                                                                                                                          - A Payment instance p was created (instance creation).

                                                                                                                                                                                                                                                                                                                          - p.amountTendered 变为 amount (属性修改)。

                                                                                                                                                                                                                                                                                                                          - p.amountTendered became amount (attribute modification).

                                                                                                                                                                                                                                                                                                                          - p 与当前销售相关联(已形成关联)。

                                                                                                                                                                                                                                                                                                                          - p was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                          - 当前销售与品牌旗舰店关联(已形成关联);(将其添加到已完成销售的历史日志中)

                                                                                                                                                                                                                                                                                                                          - The current Sale was associated with the Store (association formed); (to add it to the historical log of completed sales)



                                                                                                                                                                                                                                                                                                                          对 POS 域模型的更改

                                                                                                                                                                                                                                                                                                                          Changes to the POS Domain Model

                                                                                                                                                                                                                                                                                                                          这些合同至少建议了一点,但尚未在领域模型中表示:完成 item entry to the sale。endSale 规范对其进行了修改,在以后的设计工作中,最好让 makePayment 操作对其进行测试,在销售完成之前禁止付款(这意味着,无需添加更多项目)。

                                                                                                                                                                                                                                                                                                                          There is at least one point suggested by these contracts that is not yet represented in the domain model: completion of item entry to the sale. The endSale specification modifies it, and it is probably a good idea later during design work for the makePayment operation to test it, to disallow payments until a sale is complete (meaning, no more items to add).

                                                                                                                                                                                                                                                                                                                          表示此信息的一种方法是在 Sale 中使用 isComplete 属性:

                                                                                                                                                                                                                                                                                                                          One way to represent this information is with an isComplete attribute in the Sale:

                                                                                                                                                                                                                                                                                                                          还有其他选择,尤其是在设计工作中考虑。一种技术称为 State 模式。另一个是使用 “session” 对象来跟踪 session 的状态并禁止无序操作;这将在后面探讨。

                                                                                                                                                                                                                                                                                                                          There are alternatives, especially considered during design work. One technique is called the State pattern. Another is the use of "session" objects that track the state of a session and disallow out-of-order operations; this will be explored later.

                                                                                                                                                                                                                                                                                                                            11.10. 示例:垄断合同

                                                                                                                                                                                                                                                                                                                            11.10. Example: Monopoly Contracts

                                                                                                                                                                                                                                                                                                                            我将使用这个案例研究来强调,许多分析工件并不总是需要的,包括合同。UP 鼓励避免创建工件,除非它解决了风险或解决了实际问题。从儿童或青少年的经验中了解游戏规则的人(似乎大多数人)可以在不看很多书面细节的情况下实施它。

                                                                                                                                                                                                                                                                                                                            I'll use this case study to emphasize that many analysis artifacts aren't always needed, including contracts. The UP encourages avoiding creating an artifact unless it addresses a risk or solves a real problem. People who know the rules of the game from experience as a child or teenager (most people, it seems) can implement it without looking at many written details.

                                                                                                                                                                                                                                                                                                                              11.11. 应用 UML:操作、合约和 OCL

                                                                                                                                                                                                                                                                                                                              11.11. Applying UML: Operations, Contracts, and the OCL

                                                                                                                                                                                                                                                                                                                              本章中的合约和 UML 之间有什么关系?

                                                                                                                                                                                                                                                                                                                              What's the relationship between contracts in this chapter and the UML?

                                                                                                                                                                                                                                                                                                                              UML 正式定义了操作。引用:

                                                                                                                                                                                                                                                                                                                              The UML formally defines operations. To quote:

                                                                                                                                                                                                                                                                                                                              操作是可以调用对象来执行的转换或查询的规范。[RJB99]

                                                                                                                                                                                                                                                                                                                              An operation is a specification of a transformation or query that an object may be called to execute. [RJB99]

                                                                                                                                                                                                                                                                                                                              例如,在 UML 术语中,接口的元素是操作。操作是一种抽象,而不是一种实现。相比之下,方法(在 UML 中)是操作的实现。引用:

                                                                                                                                                                                                                                                                                                                              For example, the elements of an interface are operations, in UML terms. An operation is an abstraction, not an implementation. By contrast, a method (in the UML) is an implementation of an operation. To quote:

                                                                                                                                                                                                                                                                                                                              [方法是] 操作的实现。它指定与操作关联的算法或过程。[OMG03a]]

                                                                                                                                                                                                                                                                                                                              [A method is] the implementation of an operation. It specifies the algorithm or procedure associated with an operation. [OMG03a]

                                                                                                                                                                                                                                                                                                                              在 UML 元模型中,操作具有签名(名称和参数),最重要的是,在此上下文中,它与一组 UML Constraint 对象相关联,这些对象被分类为指定操作语义的前提条件和后置条件。

                                                                                                                                                                                                                                                                                                                              In the UML metamodel, an operation has a signature (name and parameters), and most importantly in this context, is associated with a set of UML Constraint objects classified as preconditions and postconditions that specify the semantics of the operation.

                                                                                                                                                                                                                                                                                                                              总结一下:UML 通过约束定义操作语义,这些约束可以在前条件和后条件样式中指定。请注意,正如本章所强调的,UML 操作规范不能显示算法或解决方案,而只能显示操作的状态更改或效果。

                                                                                                                                                                                                                                                                                                                              To summarize: The UML defines operation semantics via constraints, which are specifiable in the pre- and post-condition style. Note that, as emphasized in this chapter, a UML operation specification can not show an algorithm or solution, but only the state changes or effects of the operation.

                                                                                                                                                                                                                                                                                                                              除了使用 Contract 指定整个系统的公共操作(即系统操作)之外,Contract 还可以应用于任何粒度级别的操作:子系统的公共操作(或接口)、组件、抽象类等。例如,可以为单个软件类(如 Stack)定义操作。本章中讨论的粗粒度操作属于 System 类,该类将整个系统表示为黑盒组件,但在 UML 中,操作可以属于任何类或接口,所有这些都具有前置条件和后置条件。

                                                                                                                                                                                                                                                                                                                              In addition to using contracts to specify public operations of the entire System (that is, system operations), contracts can be applied to operations at any level of granularity: the public operations (or interface) of a subsystem, a component, an abstract class, and so forth. For example, operations can be defined for a single software class such as a Stack. The coarse-grained operations discussed in this chapter belong to a System class representing the overall system as a black box component, but in the UML operations can belong to any class or interface, all with pre- and post-conditions.

                                                                                                                                                                                                                                                                                                                              使用 OCL 表示的运营合同

                                                                                                                                                                                                                                                                                                                              Operation Contracts Expressed with the OCL

                                                                                                                                                                                                                                                                                                                              本章中的前提条件和后条件格式是非正式的自然语言,在 UML 中是完全可以接受的,并且希望易于理解。

                                                                                                                                                                                                                                                                                                                              The pre- and post-condition format in this chapter is informal natural languageperfectly acceptable in the UML, and desirable to be easily understood.

                                                                                                                                                                                                                                                                                                                              但与 UML 相关的还有一种正式的、严格的语言,称为对象约束语言 (OCL) [WK99],它可用于表示 UML 操作的约束。

                                                                                                                                                                                                                                                                                                                              But also associated with the UML is a formal, rigorous language called the Object Constraint Language (OCL) [WK99], which can be used to express constraints of UML operations.

                                                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                                                              除非有令人信服的实际理由要求人们学习和使用 OCL,否则请保持简单并使用自然语言。虽然我确信有真实有用的应用程序,但我从未见过使用 OCL 的项目,即使我访问了许多客户和项目。

                                                                                                                                                                                                                                                                                                                              Unless there is a compelling practical reason to require people to learn and use the OCL, keep things simple and use natural language. Although I'm sure there are realand usefulapplications, I've never seen a project that used OCL, even though I visit many clients and projects.



                                                                                                                                                                                                                                                                                                                              OCL 定义了一种官方格式,用于指定操作的前提条件和后置条件,如以下片段所示:

                                                                                                                                                                                                                                                                                                                              The OCL defines an official format for specifying pre- and postconditions for operations, as demonstrated in this fragment:

                                                                                                                                                                                                                                                                                                                              System::makeNewSale( )
                                                                                                                                                                                                                                                                                                                                 pre : <statements in OCL>
                                                                                                                                                                                                                                                                                                                                 post : …
                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                              System::makeNewSale( )
                                                                                                                                                                                                                                                                                                                                 pre : <statements in OCL>
                                                                                                                                                                                                                                                                                                                                 post : …
                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                              OCL 的更多细节超出了本介绍的范围。

                                                                                                                                                                                                                                                                                                                              Further OCL details are beyond the scope of this introduction.

                                                                                                                                                                                                                                                                                                                                11.12. 流程:UP 内的运营合同

                                                                                                                                                                                                                                                                                                                                11.12. Process: Operation Contracts Within the UP

                                                                                                                                                                                                                                                                                                                                前条件和后条件协定是一种众所周知的样式,用于在 UML 中指定操作。在 UML 中,操作存在于许多级别,从 System 到细粒度类,例如 Sale系统级别的操作合同是用例模型的一部分,尽管它们在原始 RUP 或 UP 文档中没有正式强调;它们包含在该模型中已与 RUP 作者进行了验证。[1]

                                                                                                                                                                                                                                                                                                                                A pre- and postcondition contract is a well-known style to specify an operation in the UML. In the UML, operations exists at many levels, from System down to fine-grained classes, such as Sale. Operation contracts for the System level are part of the Use-Case Model, although they were not formally highlighted in the original RUP or UP documentation; their inclusion in this model was verified with the RUP authors.[1]

                                                                                                                                                                                                                                                                                                                                [1] 私人通信。

                                                                                                                                                                                                                                                                                                                                [1] Private communication.

                                                                                                                                                                                                                                                                                                                                阶段

                                                                                                                                                                                                                                                                                                                                Phases

                                                                                                                                                                                                                                                                                                                                初始合同在开始时没有动机它们太详细了。

                                                                                                                                                                                                                                                                                                                                Inception Contracts are not motivated during inceptionthey are too detailed.

                                                                                                                                                                                                                                                                                                                                阐述如果有使用,大多数 Contract 将在 elaboration 期间编写,此时大多数用例都已编写。只为最复杂和最微妙的系统操作编写 Contract。

                                                                                                                                                                                                                                                                                                                                Elaboration If used at all, most contracts will be written during elaboration, when most use cases are written. Only write contracts for the most complex and subtle system operations.

                                                                                                                                                                                                                                                                                                                                  11.13. 历史

                                                                                                                                                                                                                                                                                                                                  11.13. History

                                                                                                                                                                                                                                                                                                                                  操作合同来自计算机科学的正式规范领域,最初来自多产的 Tony Hoare。霍尔在 1960 年代中期在工业界工作,开发 ALGOL 60 编译器,并阅读了伯特兰·罗素 (Bertrand Russell) 的《数学哲学导论》,该书向他介绍了公理理论和断言的概念。他意识到计算机程序可以用相对于程序启动和终止时预期结果的断言(前条件和后条件)来表示。1968 年,他加入学术界,他的想法与其他研究人员的形式规范理论一起传播开来。

                                                                                                                                                                                                                                                                                                                                  Operation contracts come out of the formal specifications area in computer science, originally from the prolific Tony Hoare. Hoare was working in industry in the mid-1960s to develop an ALGOL 60 compiler and read Bertrand Russell's Introduction to Mathematical Philosophy, which introduced him to the idea of axiomatic theory and assertions. He realized that computer programs could be expressed with assertions (pre- and post-conditions) relative to the results that were expected at the launch and termination of a program. In 1968 he joined academia, and his idea spread, along with other researchers' theories of formal specifications.

                                                                                                                                                                                                                                                                                                                                  1974 年,在维也纳的 IBM 实验室,正在开发一个 PL/1 编译器,研究人员希望有一个明确的正式语言规范。出于这种需求,VDL维也纳定义语言由 Peter Lucas 诞生。VDL 借用了 Hoare 和 Russel 之前探索的 pre- condition-condition assert 形式。VDL 最终演变成维也纳定义方法 (VDM) 中使用的语言,这是一种应用操作合同形式规范和严格证明理论 [BJ78] 的方法。

                                                                                                                                                                                                                                                                                                                                  In 1974 at the IBM Lab in Vienna a PL/1 compiler was being developed, and the researchers desired an unambiguous formal specification of the language. Out of this need VDLthe Vienna Definition Languagewas born by Peter Lucas. VDL borrowed the pre- and post-condition assertion form earlier explored by Hoare and Russel. VDL eventually evolved into the language used within the Vienna Definition Method (VDM), a method that applied operation contract formal specifications and rigorous proof theory [BJ78].

                                                                                                                                                                                                                                                                                                                                  在 1980 年代,Bertrand Meyer 毫不奇怪,另一位编译器作者(OO 语言 Eiffel)开始推广使用前条件和后条件断言作为其 Eiffel 语言中的第一类元素,以应用于 OOA/D。在他的畅销书《面向对象的软件构造》中,他为更广泛地了解正式规范和操作合同做出了贡献,其中他还提出了一种方法,称为合同设计 (DBC)。在 DBC 中,Contract 是为细粒度软件类操作的操作编写的,而不是专门针对整个“系统”的公共操作编写的。此外,DBC 还促进了一个不变部分,这在全面的 Contract 规范中很常见。不变量定义在操作执行之前和之后不得更改状态的事物。为简单起见,本章中未使用固定条件。

                                                                                                                                                                                                                                                                                                                                  In the 1980s, Bertrand Meyernot surprisingly yet another compiler writer (the OO language Eiffel)started to promote the use of pre- and post-condition assertions as first-class elements within his Eiffel language, to be applied to OOA/D. He contributed to a much wider awareness of formal specifications and operation contracts in his popular book Object-Oriented Software Construction, in which he also proposed the approach as a method called Design by Contract (DBC). In DBC, contracts are written for operations of fine-grained software class operations, not specifically the public operations of the overall "system." In addition, DBC promotes an invariant section, common in thorough contract specifications. Invariants define things that must not change state before and after the operation has executed. Invariants have not been used in this chapter for the sake of simplicity.

                                                                                                                                                                                                                                                                                                                                  在 1990 年代初期,Grady Booch 在他的 Booch 方法中简要讨论了将 Contract 应用于对象操作。此外,HP 实验室的 Derek Coleman 和同事借鉴了操作合同思想,并将其应用于 OOA 和域建模,使其成为有影响力的 OOA/D 融合方法 [Coleman+94] 的一部分。

                                                                                                                                                                                                                                                                                                                                  In the early 1990s, Grady Booch briefly discussed applying contracts to object operations in his Booch Method. Also, Derek Coleman and colleagues at HP Labs borrowed the operation contract idea and applied it to OOA and domain modeling, making it part of the influential OOA/D Fusion method [Coleman+94].

                                                                                                                                                                                                                                                                                                                                  Contract 的编程语言支持

                                                                                                                                                                                                                                                                                                                                  Programming Language Support for Contracts

                                                                                                                                                                                                                                                                                                                                  某些语言(如 Eiffel)对不变量以及前后条件提供一流的支持。例如,使用属性、Javadoc 标记或预编译器,可以在 Java 和 C# 中提供类似的工具。

                                                                                                                                                                                                                                                                                                                                  Some languages, such as Eiffel, have first-class support for invariants and pre- and post-conditions. Using attributes, Javadoc tags, or pre-compilers, similar facilities can be provided in Java and C#, for example.

                                                                                                                                                                                                                                                                                                                                    11.14. 推荐资源

                                                                                                                                                                                                                                                                                                                                    11.14. Recommended Resources

                                                                                                                                                                                                                                                                                                                                    许多面向 OOA 的系统操作契约示例可以在 Coleman 等人的面向对象的开发:融合方法中找到。等人。Meyer 的 Object-Oriented Software Construction 展示了 Eiffel 中的许多程序级契约示例。在 UML 中,还可以在对象约束语言 (OCL) 中更严格地指定操作协定,为此建议使用 Warmer 和 Kleppe 的 The Object Constraint Language: Precise Modeling with UML

                                                                                                                                                                                                                                                                                                                                    Many examples of OOA-oriented system operation contracts can be found in Object-Oriented Development: The Fusion Method by Coleman, et. al. Object-Oriented Software Construction by Meyer shows many program-level contract examples in Eiffel. Within the UML, operation contracts can also be specified more rigorously in the Object Constraint Language (OCL), for which Warmer and Kleppe's The Object Constraint Language: Precise Modeling with UML is recommended.

                                                                                                                                                                                                                                                                                                                                      第 12 章.DesignIteratively 的要求

                                                                                                                                                                                                                                                                                                                                      Chapter 12. Requirements to DesignIteratively

                                                                                                                                                                                                                                                                                                                                      硬件,n.:计算机系统中可以踢出的部分。

                                                                                                                                                                                                                                                                                                                                      匿名

                                                                                                                                                                                                                                                                                                                                      Hardware, n.: The parts of a computer system that can be kicked.

                                                                                                                                                                                                                                                                                                                                      anonymous

                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                      • 快速激励过渡到设计活动。

                                                                                                                                                                                                                                                                                                                                      • Quickly motivate the transition to design activities.

                                                                                                                                                                                                                                                                                                                                      • 对比对象设计技能与 UML 表示法知识的重要性。

                                                                                                                                                                                                                                                                                                                                      • Contrast the importance of object design skill versus UML notation knowledge.



                                                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                                                        到目前为止,案例研究强调了对需求和对象的分析。如果遵循 UP 指南,那么在开始时可能会调查 10% 的需求,并且在第一次迭代的阐述中开始了稍微深入的调查。以下章节的重点将转向根据协作软件对象为此迭代设计解决方案。

                                                                                                                                                                                                                                                                                                                                        So far, the case studies have emphasized analysis of the requirements and objects. If following the UP guidelines, perhaps 10% of the requirements were investigated in inception, and a slightly deeper investigation was started in this first iteration of elaboration. The following chapters are a shift in emphasis toward designing a solution for this iteration in terms of collaborating software objects.

                                                                                                                                                                                                                                                                                                                                          12.1. 迭代地做正确的事,把事情做对

                                                                                                                                                                                                                                                                                                                                          12.1. Iteratively Do the Right Thing, Do the Thing Right

                                                                                                                                                                                                                                                                                                                                          需求和面向对象的分析侧重于学习做正确的事情;也就是说,了解案例研究的一些突出目标,以及相关的规则和约束。相比之下,下面的设计工作将强调做正确的事情;也就是说,巧妙地设计解决方案以满足此迭代的要求。

                                                                                                                                                                                                                                                                                                                                          The requirements and object-oriented analysis has focused on learning to do the right thing; that is, understanding some of the outstanding goals for the case studies, and related rules and constraints. By contrast, the following design work will stress do the thing right; that is, skillfully designing a solution to satisfy the requirements for this iteration.

                                                                                                                                                                                                                                                                                                                                          在迭代开发中,每次迭代都会从主要的需求或分析重点过渡到主要的设计和实现重点。早期迭代将在分析活动上花费相对更多的时间。随着愿景和规范开始基于早期编程、测试和反馈稳定下来,在以后的迭代中,分析通常会减少;我们更专注于构建解决方案。

                                                                                                                                                                                                                                                                                                                                          In iterative development, a transition from primarily a requirements or analysis focus to primarily a design and implementation focus will occur in each iteration. Early iterations will spend relatively more time on analysis activities. As the vision and specifications start to stabilize based on early programming, test, and feedback, in later iterations it is common that analysis lessens; there's more focus on just building the solution.

                                                                                                                                                                                                                                                                                                                                            12.2. 激发早期变革

                                                                                                                                                                                                                                                                                                                                            12.2. Provoking Early Change

                                                                                                                                                                                                                                                                                                                                            在设计和实现工作中发现和更改一些需求是自然而健康的,尤其是在早期迭代中。迭代和进化方法“拥抱变化”尽管我们试图在早期迭代中引发这种不可避免的变化,以便我们为后续迭代有一个更稳定的目标(以及估计和时间表)。早期编程、测试和演示有助于尽早引发不可避免的变化。注意!这个简单的想法是迭代开发工作的核心。

                                                                                                                                                                                                                                                                                                                                            It is natural and healthy to discover and change some requirements during the design and implementation work, especially in the early iterations. Iterative and evolutionary methods "embrace change"although we try to provoke that inevitable change in early iterations, so that we have a more stable goal (and estimate and schedule) for the later iterations. Early programming, tests, and demos help provoke the inevitable changes early on. Take note! This simple idea lies at the heart of why iterative development works.

                                                                                                                                                                                                                                                                                                                                            发现不断变化的规范既可以阐明此迭代的设计工作的目的,也可以完善对未来迭代的需求理解。在这些早期细化迭代的过程中,需求发现应该会稳定下来,这样在细化结束时,也许 80% 的需求都是通过反馈、早期编程和测试而不是瀑布式方法中发生的猜测来可靠地定义、定义和细化的。

                                                                                                                                                                                                                                                                                                                                            The discovery of changing specifications will both clarify the purpose of the design work of this iteration and refine the requirements understanding for future iterations. Over the course of these early elaboration iterations, the requirements discovery should stabilize, so that by the end of elaboration, perhaps 80% of the requirements are reliably defineddefined and refined as a result of feedback, early programming and testing, rather than speculation, as occurs in a waterfall method.

                                                                                                                                                                                                                                                                                                                                              12.3. 所有这些分析和建模不是需要数周时间才能完成吗?

                                                                                                                                                                                                                                                                                                                                              12.3. Didn't All That Analysis and Modeling Take Weeks To Do?

                                                                                                                                                                                                                                                                                                                                              经过许多章节的详细讨论,之前的建模肯定需要数周的努力。事实并非如此!

                                                                                                                                                                                                                                                                                                                                              After many chapters of detailed discussion, it must surely seem like the prior modeling would take weeks of effort. Not so!

                                                                                                                                                                                                                                                                                                                                              当一个人对用例编写、领域建模等技能感到满意时,完成迄今为止探索的所有实际建模的持续时间实际上只有几个小时或几天。

                                                                                                                                                                                                                                                                                                                                              When one is comfortable with the skills of use case writing, domain modeling, and so forth, the duration to do all the actual modeling that has been explored so far is realistically just a few hours or days.

                                                                                                                                                                                                                                                                                                                                              然而,这并不意味着自项目开始以来只过去了几天。许多其他活动,例如概念验证编程、查找资源(人员、软件等)、规划、设置环境等,可能需要几周的准备时间。

                                                                                                                                                                                                                                                                                                                                              However, that does not mean that only a few days have passed since the start of the project. Many other activities, such as proof-of-concept programming, finding resources (people, software, …), planning, setting up the environment, and so on, could consume a few weeks of preparation.

                                                                                                                                                                                                                                                                                                                                                第 13 章.逻辑体系结构和 UML 包图

                                                                                                                                                                                                                                                                                                                                                Chapter 13. Logical Architecture and UML Package Diagrams

                                                                                                                                                                                                                                                                                                                                                0x2B |~0x2B

                                                                                                                                                                                                                                                                                                                                                哈姆雷特

                                                                                                                                                                                                                                                                                                                                                0x2B | ~0x2B

                                                                                                                                                                                                                                                                                                                                                Hamlet

                                                                                                                                                                                                                                                                                                                                                目标

                                                                                                                                                                                                                                                                                                                                                Objectives

                                                                                                                                                                                                                                                                                                                                                • 引入使用层的逻辑体系结构。

                                                                                                                                                                                                                                                                                                                                                • Introduce a logical architecture using layers.

                                                                                                                                                                                                                                                                                                                                                • 使用 UML 封装图说明逻辑体系结构。

                                                                                                                                                                                                                                                                                                                                                • Illustrate the logical architecture using UML package diagrams.



                                                                                                                                                                                                                                                                                                                                                  介绍

                                                                                                                                                                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                                                                                                                                                                  首先,设置期望级别:这是对逻辑体系结构主题的非常简短的介绍,这是一个相当大的主题。从第 559 页开始了解更多信息。

                                                                                                                                                                                                                                                                                                                                                  First, to set the expectation level: This is a very short introduction to the topic of logical architecture, a fairly large topic. Learn more starting on p. 559.

                                                                                                                                                                                                                                                                                                                                                  现在我们已经从面向分析的工作过渡到软件设计,让我们从大规模开始。在此级别,典型 OO 系统的设计基于多个体系结构层,例如 UI 层、应用程序逻辑(或“域”)层等。本章简要探讨了逻辑分层体系结构和相关的 UML 表示法。

                                                                                                                                                                                                                                                                                                                                                  Now that we have transitioned from analysis-oriented work to software design, let's start with the large-scale. At this level, the design of a typical OO system is based on several architectural layers, such as a UI layer, an application logic (or "domain") layer, and so forth. This chapter briefly explores a logical layered architecture and related UML notation.

                                                                                                                                                                                                                                                                                                                                                  UP 工件影响,强调逻辑架构 (LA),如图 13.1 所示。UML 封装图可以作为设计模型的一部分来说明 LA,也可以在软件体系结构文档中总结为视图。主要输入是补充规范中捕获的架构力量。LA 定义定义在其中定义软件类的软件包。

                                                                                                                                                                                                                                                                                                                                                  UP artifact influence, emphasizing the logical architecture (LA), is shown in Figure 13.1. UML package diagrams may illustrate the LA as part of the Design Modeland also be summarized as a view in the Software Architecture Document. The prime input is the architectural forces captured in the Supplementary Specification. The LA defines the packages within which software classes are defined.

                                                                                                                                                                                                                                                                                                                                                  图 13.1.示例 UP 伪影影响。



                                                                                                                                                                                                                                                                                                                                                    13.1. 示例

                                                                                                                                                                                                                                                                                                                                                    13.1. Example

                                                                                                                                                                                                                                                                                                                                                    图 13.2 显示了使用 UML 包图表示法绘制的部分分层逻辑体系结构。

                                                                                                                                                                                                                                                                                                                                                    Figure 13.2 shows a partial layered, logical architecture drawn with UML package diagram notation.

                                                                                                                                                                                                                                                                                                                                                    图 13.2.使用 UML 包图表示法显示的层。



                                                                                                                                                                                                                                                                                                                                                      13.2. 什么是逻辑架构?图层呢?

                                                                                                                                                                                                                                                                                                                                                      13.2. What is the Logical Architecture? And Layers?

                                                                                                                                                                                                                                                                                                                                                      逻辑体系结构是将软件类大规模组织成包(或命名空间)、子系统和层。之所以称为逻辑体系结构,是因为没有关于如何在不同的操作系统进程或网络中的物理计算机上部署这些元素的决定(后一个决策是部署体系结构的一部分)。

                                                                                                                                                                                                                                                                                                                                                      The logical architecture is the large-scale organization of the software classes into packages (or namespaces), subsystems, and layers. It's called the logical architecture because there's no decision about how these elements are deployed across different operating system processes or across physical computers in a network (these latter decisions are part of the deployment architecture).

                                                                                                                                                                                                                                                                                                                                                      是类、包或子系统的非常粗粒度的分组,它们对系统的主要方面具有内聚责任。此外,层的组织方式是使“较高”层(例如 UI 层)调用“较低”层的服务,但通常不是相反。通常,OO 系统中的层包括:

                                                                                                                                                                                                                                                                                                                                                      A layer is a very coarse-grained grouping of classes, packages, or subsystems that has cohesive responsibility for a major aspect of the system. Also, layers are organized such that "higher" layers (such as the UI layer) call upon services of "lower" layers, but not normally vice versa. Typically layers in an OO system include:

                                                                                                                                                                                                                                                                                                                                                      • 用户界面

                                                                                                                                                                                                                                                                                                                                                      • User Interface.

                                                                                                                                                                                                                                                                                                                                                      • Application Logic 和 Domain Objects 软件对象表示满足应用程序要求(例如,计算销售总额)的域概念 (例如,软件类 Sale)。

                                                                                                                                                                                                                                                                                                                                                      • Application Logic and Domain Objects software objects representing domain concepts (for example, a software class Sale) that fulfill application requirements, such as calculating a sale total.

                                                                                                                                                                                                                                                                                                                                                      • 技术服务 提供支持技术服务(例如,与数据库连接或错误日志记录)的通用对象和子系统。这些服务通常独立于应用程序,并且可以在多个系统中重复使用。

                                                                                                                                                                                                                                                                                                                                                      • Technical Services general purpose objects and subsystems that provide supporting technical services, such as interfacing with a database or error logging. These services are usually application-independent and reusable across several systems.

                                                                                                                                                                                                                                                                                                                                                      严格的分层架构中,层只调用其正下方层的服务。这种设计在网络协议栈中很常见,但在信息系统中并不常见,信息系统通常具有宽松的分层架构,其中较高层调用多个较低层。例如,UI 层可以调用其直接从属的应用程序逻辑层,也可以调用较低技术服务层的元素进行日志记录等。

                                                                                                                                                                                                                                                                                                                                                      In a strict layered architecture, a layer only calls upon the services of the layer directly below it. This design is common in network protocol stacks, but not in information systems, which usually have a relaxed layered architecture, in which a higher layer calls upon several lower layers. For example, the UI layer may call upon its directly subordinate application logic layer, and also upon elements of a lower technical service layer, for logging and so forth.

                                                                                                                                                                                                                                                                                                                                                      逻辑体系结构不必按层进行组织。但它很常见,因此在这个时候引入。

                                                                                                                                                                                                                                                                                                                                                      A logical architecture doesn't have to be organized in layers. But it's very common, and hence, introduced at this time.

                                                                                                                                                                                                                                                                                                                                                        13.3. 案例研究的重点是什么?

                                                                                                                                                                                                                                                                                                                                                        13.3. What Layers are the Focus in the Case Studies?

                                                                                                                                                                                                                                                                                                                                                        重申一下在介绍案例研究时提出的观点:

                                                                                                                                                                                                                                                                                                                                                        To reiterate a point made when the case studies were introduced:



                                                                                                                                                                                                                                                                                                                                                        尽管 OO 技术可以应用于所有级别,但 OOA/D 的介绍侧重于核心应用程序逻辑(或“域”)层,并对其他层进行一些次要讨论。

                                                                                                                                                                                                                                                                                                                                                        Although OO technology can be applied at all levels, this introduction to OOA/D focuses on the core application logic (or "domain") layer, with some secondary discussion of the other layers.



                                                                                                                                                                                                                                                                                                                                                        探索其他层(例如 UI 层)的设计将侧重于它们与 application logic 层的接口的设计。

                                                                                                                                                                                                                                                                                                                                                        Exploring design of the other layers (such as the UI layer) will focus on the design of their interface to the application logic layer.

                                                                                                                                                                                                                                                                                                                                                        41 页的讨论简要地解释了为什么其他层往往非常依赖于技术(例如,非常特定于 Java 或 .NET),并且在任何情况下,在应用程序逻辑(域)层的上下文中学到的 OO 设计经验教训适用于所有其他层或组件。

                                                                                                                                                                                                                                                                                                                                                        The discussion on p. 41 explains, but in brief, why the other layers tend to be very technology dependent (for example, very specific to Java or .NET), and in any case the OO design lessons learned in the context of the application logic (domain) layer are applicable to all other layers or components.

                                                                                                                                                                                                                                                                                                                                                          13.4. 什么是软件架构?

                                                                                                                                                                                                                                                                                                                                                          13.4. What is Software Architecture?

                                                                                                                                                                                                                                                                                                                                                          我谈到了逻辑架构和部署架构,所以现在是介绍软件架构定义的好时机。这里有一个:

                                                                                                                                                                                                                                                                                                                                                          I touched on the logical and deployment architectures, so now is a good time to introduce a definition for software architecture. Here's one:

                                                                                                                                                                                                                                                                                                                                                          架构是关于软件系统组织的一组重要决策,结构元素及其组成系统的接口的选择,以及它们在这些元素之间的协作中指定的行为,这些结构和行为元素组成逐渐更大的子系统,以及指导这种组织的架构风格这些元素及其接口, 他们的合作和他们的组成。[BRJ99]

                                                                                                                                                                                                                                                                                                                                                          An architecture is the set of significant decisions about the organization of a software system, the selection of the structural elements and their interfaces by which the system is composed, together with their behavior as specified in the collaborations among those elements, the composition of these structural and behavioral elements into progressively larger subsystems, and the architectural style that guides this organizationthese elements and their interfaces, their collaborations, and their composition. [BRJ99]

                                                                                                                                                                                                                                                                                                                                                          无论定义如何(有很多),所有软件架构定义的共同主题是它与系统(或系统系统)的动机、约束、组织、模式、责任和连接的大规模大思想有关。

                                                                                                                                                                                                                                                                                                                                                          Regardless of the definition (and there are many) the common theme in all software architecture definitions is that it has to do with the large scalethe Big Ideas in the motivations, constraints, organization, patterns, responsibilities, and connections of a system (or a system of systems).

                                                                                                                                                                                                                                                                                                                                                            13.5. 应用 UML:封装图

                                                                                                                                                                                                                                                                                                                                                            13.5. Applying UML: Package Diagrams

                                                                                                                                                                                                                                                                                                                                                            UML 包图通常用于说明系统的逻辑架构层、子系统、包(在 Java 意义上)等。层可以建模为 UML 包;例如,建模为名为 UI 的包的 UI 层。

                                                                                                                                                                                                                                                                                                                                                            UML package diagrams are often used to illustrate the logical architecture of a systemthe layers, subsystems, packages (in the Java sense), etc. A layer can be modeled as a UML package; for example, the UI layer modeled as a package named UI.

                                                                                                                                                                                                                                                                                                                                                            UML 包图提供了一种对元素进行分组的方法。UML 包可以对任何内容进行分组:类、其他包、用例等。嵌套包非常常见。UML 包是一个更通用的概念,而不仅仅是 Java 包或 .NET 命名空间,尽管 UML 包可以表示它们以及更多。

                                                                                                                                                                                                                                                                                                                                                            A UML package diagram provides a way to group elements. A UML package can group anything: classes, other packages, use cases, and so on. Nesting packages is very common. A UML package is a more general concept than simply a Java package or .NET namespace, though a UML package can represent thoseand more.

                                                                                                                                                                                                                                                                                                                                                            如果包显示内部成员,则包名称可以放在选项卡上,如果没有,则可以放在主文件夹中。

                                                                                                                                                                                                                                                                                                                                                            The package name may be placed on the tab if the package shows inner members, or on the main folder, if not.

                                                                                                                                                                                                                                                                                                                                                            通常希望显示 package 之间的依赖关系(耦合),以便开发人员可以看到系统中的大规模耦合。UML 依赖关系线用于此目的,这是一条带有箭头的虚线,箭头指向被依赖的包。

                                                                                                                                                                                                                                                                                                                                                            It is common to want to show dependency (a coupling) between packages so that developers can see the large-scale coupling in the system. The UML dependency line is used for this, a dashed arrowed line with the arrow pointing towards the depended-on package.

                                                                                                                                                                                                                                                                                                                                                            UML 包表示一个命名空间,因此,例如,可以在两个包中定义 Date 类。如果需要提供完全限定名称,则 UML 表示法为 java::util::D ate,例如,如果存在一个名为“java”的外部包和一个名为“util”的嵌套包和一个 Date 类。

                                                                                                                                                                                                                                                                                                                                                            A UML package represents a namespace so that, for example, a Date class may be defined in two packages. If you need to provide fully-qualified names, the UML notation is, for example, java::util::Date in the case that there was an outer package named "java" with a nested package named "util" with a Date class.

                                                                                                                                                                                                                                                                                                                                                            UML 提供了替代表示法来说明外部和内部嵌套包。有时,在内包装周围绘制一个外包装盒是很尴尬的。替代方案如图 13.3 所示。

                                                                                                                                                                                                                                                                                                                                                            The UML provides alternate notations to illustrate outer and inner nested packages. Sometimes it is awkward to draw an outer package box around inner packages. Alternatives are shown in Figure 13.3.

                                                                                                                                                                                                                                                                                                                                                            图 13.3.使用嵌入式包、UML 完全限定名称和圆叉符号来显示包嵌套的替代 UML 方法。



                                                                                                                                                                                                                                                                                                                                                            UML 工具:从代码对包图进行逆向工程

                                                                                                                                                                                                                                                                                                                                                            UML Tools: Reverse-engineer Package Diagrams from Code

                                                                                                                                                                                                                                                                                                                                                            在早期开发过程中,我们可能会绘制一个 UML 包图,然后根据这些包草图来组织我们的代码。随着时间的推移,代码库会增长,我们花更多的时间编程,而花在建模或 UML 图上的时间会更少。此时,UML CASE 工具的一个很好的用途是对源代码进行逆向工程并自动生成封装图。

                                                                                                                                                                                                                                                                                                                                                            During early development, we may sketch a UML package diagram and then organize our code according to these package sketches. Over time, the code base grows and we spend more time programming and less on modeling or UML diagrams. At that point, a great use for a UML CASE tool is to reverse-engineer the source code and generate a package diagram automatically.

                                                                                                                                                                                                                                                                                                                                                            如果我们使用第 204 页中为代码包建议的命名约定,这种做法会得到增强。

                                                                                                                                                                                                                                                                                                                                                            This practice is enhanced if we use the naming conventions on p. 204 suggested for code packages.

                                                                                                                                                                                                                                                                                                                                                              13.6. 指南:使用图层进行设计

                                                                                                                                                                                                                                                                                                                                                              13.6. Guideline: Design with Layers

                                                                                                                                                                                                                                                                                                                                                              使用 layers [BMRSS96] 的基本思路很简单:

                                                                                                                                                                                                                                                                                                                                                              The essential ideas of using layers [BMRSS96] are simple:

                                                                                                                                                                                                                                                                                                                                                              • 将系统的大规模逻辑结构组织成不同、相关职责的离散层,并清晰、内聚地分离关注点,以便“较低”层是低级和通用服务,而较高层则更特定于应用程序。

                                                                                                                                                                                                                                                                                                                                                              • Organize the large-scale logical structure of a system into discrete layers of distinct, related responsibilities, with a clean, cohesive separation of concerns such that the "lower" layers are low-level and general services, and the higher layers are more application specific.

                                                                                                                                                                                                                                                                                                                                                              • 协作和耦合是从高层到底层的;避免了从低层到高层的耦合。

                                                                                                                                                                                                                                                                                                                                                              • Collaboration and coupling is from higher to lower layers; lower-to-higher layer coupling is avoided.

                                                                                                                                                                                                                                                                                                                                                              从第 559 页开始,稍后将介绍更多设计问题。这个想法在 [BMRSS96] 中被描述为 Layers 模式,并产生一个分层架构。它作为一种模式被应用和撰写得如此频繁,以至于 Pattern Almanac 2000 [Rising00] 列出了 100 多种模式,这些模式是 Layers 模式的变体或与之相关。

                                                                                                                                                                                                                                                                                                                                                              Some more design issues are covered later, starting on p. 559. The idea is described as the Layers pattern in [BMRSS96] and produces a layered architecture. It has been applied and written about so often as a pattern that the Pattern Almanac 2000 [Rising00] lists over 100 patterns that are variants of or related to the Layers pattern.

                                                                                                                                                                                                                                                                                                                                                              使用 layers 有助于解决以下几个问题:

                                                                                                                                                                                                                                                                                                                                                              Using layers helps address several problems:

                                                                                                                                                                                                                                                                                                                                                              • 源代码更改在整个系统中产生涟漪,系统的许多部分都是高度耦合的。

                                                                                                                                                                                                                                                                                                                                                              • Source code changes are rippling throughout the systemmany parts of the systems are highly coupled.

                                                                                                                                                                                                                                                                                                                                                              • 应用程序逻辑与用户界面交织在一起,因此它不能与其他界面重用或分发到另一个处理节点。

                                                                                                                                                                                                                                                                                                                                                              • Application logic is intertwined with the user interface, so it cannot be reused with a different interface or distributed to another processing node.

                                                                                                                                                                                                                                                                                                                                                              • 潜在的通用技术服务或业务逻辑与更多特定于应用程序的逻辑交织在一起,因此它无法重用、分发到另一个节点或轻松替换为不同的实现。

                                                                                                                                                                                                                                                                                                                                                              • Potentially general technical services or business logic is intertwined with more application-specific logic, so it cannot be reused, distributed to another node, or easily replaced with a different implementation.

                                                                                                                                                                                                                                                                                                                                                              • 在不同的关注领域之间存在高度耦合。因此,很难为不同的开发人员按照明确的界限来划分工作。

                                                                                                                                                                                                                                                                                                                                                              • There is high coupling across different areas of concern. It is thus difficult to divide the work along clear boundaries for different developers.

                                                                                                                                                                                                                                                                                                                                                              层的用途和数量因应用程序和应用程序域(信息系统、操作系统等)而异。应用于信息系统,图 13.4 对典型层进行了说明和解释。

                                                                                                                                                                                                                                                                                                                                                              The purpose and number of layers varies across applications and application domains (information systems, operating systems, and so forth). Applied to information systems, typical layers are illustrated and explained in Figure 13.4.

                                                                                                                                                                                                                                                                                                                                                              图 13.4.信息系统逻辑体系结构中的公共层。[1]



                                                                                                                                                                                                                                                                                                                                                              [1] 包的宽度用于传达此图中的适用范围,但这不是通用的 UML 实践。AKA 的意思是 也称为。

                                                                                                                                                                                                                                                                                                                                                              [1] The width of the package is used to communicate range of applicability in this diagram, but this is not a general UML practice. AKA means Also known As.

                                                                                                                                                                                                                                                                                                                                                              图 13.4 中的应用层在第 567 页讨论。

                                                                                                                                                                                                                                                                                                                                                              The Application layer in Figure 13.4 is discussed on p. 567.

                                                                                                                                                                                                                                                                                                                                                              使用图层的好处

                                                                                                                                                                                                                                                                                                                                                              Benefits of Using Layers

                                                                                                                                                                                                                                                                                                                                                              • 通常,存在关注点分离、高级服务与低级服务以及应用程序特定服务与常规服务的分离。这减少了耦合和依赖关系,提高了内聚性,增加了重用潜力,并提高了清晰度。

                                                                                                                                                                                                                                                                                                                                                              • In general, there is a separation of concerns, a separation of high from low-level services, and of application-specific from general services. This reduces coupling and dependencies, improves cohesion, increases reuse potential, and increases clarity.

                                                                                                                                                                                                                                                                                                                                                              • 相关的复杂性是封装和可分解的。

                                                                                                                                                                                                                                                                                                                                                              • Related complexity is encapsulated and decomposable.

                                                                                                                                                                                                                                                                                                                                                              • 某些层可以替换为新的实现。这通常不适用于较低级别的技术服务层或基础层(例如 java.util),但对于 UI、应用程序和域层可能可用。

                                                                                                                                                                                                                                                                                                                                                              • Some layers can be replaced with new implementations. This is generally not possible for lower-level Technical Service or Foundation layers (e.g., java.util), but may be possible for UI, Application, and Domain layers.

                                                                                                                                                                                                                                                                                                                                                              • 下层包含可重用的功能。

                                                                                                                                                                                                                                                                                                                                                              • Lower layers contain reusable functions.

                                                                                                                                                                                                                                                                                                                                                              • 某些层(主要是 Domain 和 Technical Services)可以分发。

                                                                                                                                                                                                                                                                                                                                                              • Some layers (primarily the Domain and Technical Services) can be distributed.

                                                                                                                                                                                                                                                                                                                                                              • 由于逻辑分段,团队的开发得到了帮助。

                                                                                                                                                                                                                                                                                                                                                              • Development by teams is aided because of the logical segmentation.

                                                                                                                                                                                                                                                                                                                                                              指导方针:有凝聚力的责任;保持关注点分离

                                                                                                                                                                                                                                                                                                                                                              Guideline: Cohesive Responsibilities; Maintain a Separation of Concerns

                                                                                                                                                                                                                                                                                                                                                              层中对象的职责应彼此密切相关,不应与其他层的职责混合。例如,UI 层中的对象应侧重于 UI 工作,例如创建窗口和小组件、捕获鼠标和键盘事件等。应用程序逻辑或 “域” 层中的对象应侧重于应用程序逻辑,例如计算销售总额或税款,或在游戏板上移动棋子。

                                                                                                                                                                                                                                                                                                                                                              The responsibilities of the objects in a layer should be strongly related to each other and should not be mixed with responsibilities of other layers. For example, objects in the UI layer should focus on UI work, such as creating windows and widgets, capturing mouse and keyboard events, and so forth. Objects in the application logic or "domain" layer should focus on application logic, such as calculating a sales total or taxes, or moving a piece on a game board.

                                                                                                                                                                                                                                                                                                                                                              UI 对象不应执行应用程序逻辑。例如,Java Swing JFrame(窗口)对象不应包含用于计算税款或移动游戏棋子的逻辑。另一方面,应用程序逻辑类不应捕获 UI 鼠标或键盘事件。这将违反明确的关注点分离和保持高内聚的基本架构原则。

                                                                                                                                                                                                                                                                                                                                                              UI objects should not do application logic. For example, a Java Swing JFrame (window) object should not contain logic to calculate taxes or move a game piece. And on the other hand, application logic classes should not trap UI mouse or keyboard events. That would violate a clear separation of concerns and maintaining high cohesionbasic architectural principles.



                                                                                                                                                                                                                                                                                                                                                              后面的章节将更详细地探讨这些重要原则,以及模型-视图分离原则

                                                                                                                                                                                                                                                                                                                                                              Later chapters will explore these important principles, plus the Model-View Separation Principle, in greater detail.



                                                                                                                                                                                                                                                                                                                                                              代码:将代码组织映射到层和 UML 包

                                                                                                                                                                                                                                                                                                                                                              Code: Mapping Code Organization to Layers and UML Packages

                                                                                                                                                                                                                                                                                                                                                              大多数流行的 OO 语言(Java、C#、C++、Python 等)都支持包(在 C# 和 C++ 中称为命名空间)。

                                                                                                                                                                                                                                                                                                                                                              Most popular OO languages (Java, C#, C++, Python, …) provide support for packages (called namespaces in C# and C++).

                                                                                                                                                                                                                                                                                                                                                              下面是一个使用 Java 将 UML 包映射到代码的示例。图 13.2 中所示的层和包可以映射到 Java 包名称,如下所示。请注意,层名称用作 Java 包名称的一部分:

                                                                                                                                                                                                                                                                                                                                                              Here's an example, using Java, for mapping UML packages to code. The layers and packages illustrated in Figure 13.2 can map to Java package names as follows. Notice that the layer name is used as a section of the Java package name:

                                                                                                                                                                                                                                                                                                                                                              // --- UI Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.ui.swing
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.ui.web
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- DOMAIN Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // packages specific to the NextGen project
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.domain.sales
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.domain.payments
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- TECHNICAL SERVICES Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // our home-grown persistence (database) access layer
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.service.persistence
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // third party
                                                                                                                                                                                                                                                                                                                                                              org.apache.log4j
                                                                                                                                                                                                                                                                                                                                                              org.apache.soap.rpc
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- FOUNDATION Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // foundation packages that our team creates
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.util
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- UI Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.ui.swing
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.ui.web
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- DOMAIN Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // packages specific to the NextGen project
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.domain.sales
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.nextgen.domain.payments
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- TECHNICAL SERVICES Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // our home-grown persistence (database) access layer
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.service.persistence
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // third party
                                                                                                                                                                                                                                                                                                                                                              org.apache.log4j
                                                                                                                                                                                                                                                                                                                                                              org.apache.soap.rpc
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              // --- FOUNDATION Layer
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                 // foundation packages that our team creates
                                                                                                                                                                                                                                                                                                                                                              com.mycompany.util
                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                              请注意,为了支持跨项目重用,除非必要,否则我们避免在包名称中使用特定的应用程序限定符 (“nextgen”)。UI 包与 NextGen POS 应用程序相关,因此它们使用应用程序名称 com.mycompany.nextgen.ui.* 进行限定。但是我们编写的实用程序可以在许多项目之间共享,因此包名称为 com.mycompany.utils,而不是 com.mycompany.nextgen.utils

                                                                                                                                                                                                                                                                                                                                                              Notice that, to support cross-project reuse, we avoided using a specific application qualifier ("nextgen") in the package names unless necessary. The UI packages are related to the NextGen POS application, so they are qualified with the application name com.mycompany.nextgen.ui.*. But the utilities we write could be shared across many projects, hence the package name com.mycompany.utils, not com.mycompany.nextgen.utils.

                                                                                                                                                                                                                                                                                                                                                              UML 工具:从代码对包图进行逆向工程

                                                                                                                                                                                                                                                                                                                                                              如前所述,UML CASE 工具的一个很好的用途是对源代码进行逆向工程并自动生成包图。如果您在代码中使用建议的命名约定,则这种做法会得到增强。例如,如果在 UI 层的所有包中包含部分名称 “.ui.”,则 UML CASE 工具会自动将子包分组和嵌套在“ui”包下,并且您可以在代码和包图中看到分层体系结构。

                                                                                                                                                                                                                                                                                                                                                              As mentioned earlier, a great use for a UML CASE tool is to reverse-engineer the source code and generate a package diagram automatically. This practice is enhanced if you use the recommended naming conventions in code. For example, if you include the partial name ".ui." in all packages for the UI layer, then the UML CASE tool will automatically group and nest sub-packages under a "ui" package, and you can see the layered architecture in both code and package diagram.

                                                                                                                                                                                                                                                                                                                                                              定义:域层与应用程序逻辑层;域对象

                                                                                                                                                                                                                                                                                                                                                              Definition: Domain Layer vs. Application Logic Layer; Domain Objects

                                                                                                                                                                                                                                                                                                                                                              本节描述了 OO 设计中一个简单但关键的概念

                                                                                                                                                                                                                                                                                                                                                              This section describes a simple but key concept in OO design!



                                                                                                                                                                                                                                                                                                                                                              典型的软件系统具有 UI 逻辑和应用程序逻辑,例如 GUI 小部件创建和税收计算。现在,这里有一个关键问题:

                                                                                                                                                                                                                                                                                                                                                              A typical software system has UI logic and application logic, such as GUI widget creation and tax calculations. Now, here's a key question:

                                                                                                                                                                                                                                                                                                                                                              我们如何用对象设计应用程序逻辑?

                                                                                                                                                                                                                                                                                                                                                              How do we design the application logic with objects?

                                                                                                                                                                                                                                                                                                                                                              我们可以创建一个名为 XYZ 的类,并将所有必需逻辑的所有方法都放在该类中。从技术上讲,它可以工作(尽管理解和维护起来是一场噩梦),但本着 OO 思维的精神,它并不是推荐的方法。

                                                                                                                                                                                                                                                                                                                                                              We could create one class called XYZ and put all the methods, for all the required logic, in that one class. It could technically work (though be a nightmare to understand and maintain), but it isn't the recommended approach in the spirit of OO thinking.

                                                                                                                                                                                                                                                                                                                                                              那么,推荐的方法是什么呢?答案: 创建名称和信息与实际域相似的软件对象,并为它们分配应用程序逻辑责任。例如,在 POS 的现实世界中,有销售和付款。因此,在软件中,我们创建了一个 SalePayment 类,并赋予它们应用程序逻辑责任。这种软件对象称为域对象。它表示问题域空间中的事物,并具有相关的应用程序或业务逻辑,例如,Sale 对象能够计算其总数。

                                                                                                                                                                                                                                                                                                                                                              So, what is the recommended approach? Answer: To create software objects with names and information similar to the real-world domain, and assign application logic responsibilities to them. For example, in the real world of POS, there are sales and payments. So, in software, we create a Sale and Payment class, and give them application logic responsibilities. This kind of software object is called a domain object. It represents a thing in the problem domain space, and has related application or business logic, for example, a Sale object being able to calculate its total.

                                                                                                                                                                                                                                                                                                                                                              以这种方式设计对象会导致 application logic layer 更准确地称为 architecture 的 domain layer,该层包含用于处理 application logic work的 domain objects。

                                                                                                                                                                                                                                                                                                                                                              Designing objects this way leads to the application logic layer being more accurately called the domain layer of the architecturethe layer that contains domain objects to handle application logic work.

                                                                                                                                                                                                                                                                                                                                                              Domain Layer 和 Domain Model 之间有什么关系?

                                                                                                                                                                                                                                                                                                                                                              这是另一个关键点:域模型和域层之间存在关系。我们从领域模型(这是值得注意的领域概念的可视化)中寻找领域层中类名称的灵感。参见图 13.5

                                                                                                                                                                                                                                                                                                                                                              This is another key point: There's a relationship between the domain model and the domain layer. We look to the domain model (which is a visualization of noteworthy domain concepts) for inspiration for the names of classes in the domain layer. See Figure 13.5.

                                                                                                                                                                                                                                                                                                                                                              图 13.5.域层和域模型关系。



                                                                                                                                                                                                                                                                                                                                                              领域层是软件的一部分,领域模型是概念视角分析的一部分,它们不是一回事。但是,通过从领域模型创建域层,我们可以在实际领域和我们的软件设计之间实现更小的表示差距。例如,UP 域模型中的 Sale 有助于激励我们考虑在 UP 设计模型的域层中创建软件 Sale 类。

                                                                                                                                                                                                                                                                                                                                                              The domain layer is part of the software and the domain model is part of the conceptual-perspective analysisthey aren't the same thing. But by creating a domain layer with inspiration from the domain model, we achieve a lower representational gap, between the real-world domain, and our software design. For example, a Sale in the UP Domain Model helps inspire us to consider creating a software Sale class in the domain layer of the UP Design Model.

                                                                                                                                                                                                                                                                                                                                                              定义:层、层和分区

                                                                                                                                                                                                                                                                                                                                                              Definition: Tiers, Layers, and Partitions

                                                                                                                                                                                                                                                                                                                                                              体系结构中的最初概念是逻辑层,而不是物理节点,但该词已被广泛用于表示物理处理节点(或节点群集),例如“客户端层”(客户端计算机)。为了清晰起见,本书将避免使用该术语,但在阅读建筑文献时请记住这一点。

                                                                                                                                                                                                                                                                                                                                                              The original notion of a tier in architecture was a logical layer, not a physical node, but the word has become widely used to mean a physical processing node (or cluster of nodes), such as the "client tier" (the client computer). This book will avoid the term for clarity, but bear this in mind when reading architecture literature.

                                                                                                                                                                                                                                                                                                                                                              据说架构的表示垂直切片,而分区表示层中相对平行的子系统的水平划分。例如,技术服务层可以分为 SecurityReporting 等分区(图 13.6)。

                                                                                                                                                                                                                                                                                                                                                              The layers of an architecture are said to represent the vertical slices, while partitions represent a horizontal division of relatively parallel subsystems of a layer. For example, the Technical Services layer may be divided into partitions such as Security and Reporting (Figure 13.6).

                                                                                                                                                                                                                                                                                                                                                              图 13.6.层和分区。



                                                                                                                                                                                                                                                                                                                                                              指南:不要将外部资源显示为底层

                                                                                                                                                                                                                                                                                                                                                              Guideline: Don't Show External Resources as the Bottom Layer

                                                                                                                                                                                                                                                                                                                                                              大多数系统都依赖于外部资源或服务,例如 MySQL 清单数据库和 Novell LDAP 名称和目录服务。这些是物理实现组件,而不是 logical architecture 中的一个层。

                                                                                                                                                                                                                                                                                                                                                              Most systems rely on external resources or services, such as a MySQL inventory database and a Novell LDAP naming and directory service. These are physical implementation components, not a layer in the logical architecture.

                                                                                                                                                                                                                                                                                                                                                              例如,在 Foundation 层 “below” 层中显示外部资源(例如,特定数据库)会混淆体系结构的逻辑视图和部署视图。

                                                                                                                                                                                                                                                                                                                                                              Showing external resources such as a particular database in a layer "below" the Foundation layer (for example) mixes up the logical view and the deployment views of the architecture.

                                                                                                                                                                                                                                                                                                                                                              相反,就逻辑架构及其层而言,对一组特定的持久化数据(比如清单数据)的访问可以看作是 Domain Layer的子域Inventory子域。而提供数据库访问的通用服务可以看作是 技术服务分区 Persistence 服务。参见图 13.7

                                                                                                                                                                                                                                                                                                                                                              Rather, in terms of the logical architecture and its layers, access to a particular set of persistent data (such as inventory data) can be viewed as a sub-domain of the Domain Layerthe Inventory sub-domain. And the general services that provide access to databases may be viewed as a Technical Service partitionthe Persistence service. See Figure 13.7.

                                                                                                                                                                                                                                                                                                                                                              图 13.7.混合架构视图。



                                                                                                                                                                                                                                                                                                                                                                13.7. 指南:模型-视图分离原则

                                                                                                                                                                                                                                                                                                                                                                13.7. Guideline: The Model-View Separation Principle

                                                                                                                                                                                                                                                                                                                                                                其他包对 UI 层应该具有什么样的可见性?非窗口类应该如何与 Windows 通信?

                                                                                                                                                                                                                                                                                                                                                                What kind of visibility should other packages have to the UI layer? How should non-window classes communicate with windows?

                                                                                                                                                                                                                                                                                                                                                                指南:模型-视图分离原则

                                                                                                                                                                                                                                                                                                                                                                Guideline: Model-View Separation Principle

                                                                                                                                                                                                                                                                                                                                                                这个原则至少有两个部分:

                                                                                                                                                                                                                                                                                                                                                                This principle has at least two parts:

                                                                                                                                                                                                                                                                                                                                                                1. 不要将非 UI 对象直接连接到 UI 对象或将其耦合到 UI 对象。例如,不要让 Sale 软件对象(非 UI“域”对象)具有对 Java Swing JFrame 窗口对象的引用。为什么?因为窗口与特定应用程序相关,而(理想情况下)非窗口对象可以在新应用程序中重用或附加到新接口。

                                                                                                                                                                                                                                                                                                                                                                2. Do not connect or couple non-UI objects directly to UI objects. For example, don't let a Sale software object (a non-UI "domain" object) have a reference to a Java Swing JFrame window object. Why? Because the windows are related to a particular application, while (ideally) the non-windowing objects may be reused in new applications or attached to a new interface.

                                                                                                                                                                                                                                                                                                                                                                3. 不要将应用程序逻辑(如税务计算)放在 UI 对象方法中。UI 对象应仅初始化 UI 元素、接收 UI 事件(如鼠标单击按钮),并将应用程序逻辑请求委托给非 UI 对象(如域对象)。

                                                                                                                                                                                                                                                                                                                                                                4. Do not put application logic (such as a tax calculation) in the UI object methods. UI objects should only initialize UI elements, receive UI events (such as a mouse click on a button), and delegate requests for application logic on to non-UI objects (such as domain objects).



                                                                                                                                                                                                                                                                                                                                                                在这种情况下,model 是对象的域层的同义词(它是 1970 年代后期的一个古老的 OO 术语)。View 是 UI 对象(如窗口、网页、小程序和报表)的同义词。

                                                                                                                                                                                                                                                                                                                                                                In this context, model is a synonym for the domain layer of objects (it's an old OO term from the late 1970s). View is a synonym for UI objects, such as windows, Web pages, applets, and reports.



                                                                                                                                                                                                                                                                                                                                                                模型-视图分离原则[2] 指出,模型(域)对象不应直接了解视图 (UI) 对象,至少作为视图对象。因此,例如,RegisterSale 对象不应直接向 GUI 窗口对象 ProcessSaleFrame 发送消息,要求它显示某些内容、更改颜色、关闭等。

                                                                                                                                                                                                                                                                                                                                                                The Model-View Separation principle[2] states that model (domain) objects should not have direct knowledge of view (UI) objects, at least as view objects. So, for example, a Register or Sale object should not directly send a message to a GUI window object ProcessSaleFrame, asking it to display something, change color, close, and so forth.

                                                                                                                                                                                                                                                                                                                                                                [2] 这是模型-视图-控制器 (MVC) 模式中的一个关键原则。MVC 最初是一种小规模的 Smalltalk-80 模式,以及相关的数据对象(模型)、GUI 小部件(视图)以及鼠标和键盘事件处理程序(控制器)。最近,“MVC”一词已被分布式设计社区采用,也适用于大规模架构级别。模型是域层,视图是 UI 层,控制器是应用程序层中的工作流对象。

                                                                                                                                                                                                                                                                                                                                                                [2] This is a key principle in the pattern Model-View-Controller (MVC). MVC was originally a small-scale Smalltalk-80 pattern, and related data objects (models), GUI widgets (views), and mouse and keyboard event handlers (controllers). More recently, the term "MVC" has been coopted by the distributed design community to also apply on a large-scale architectural level. The Model is the Domain Layer, the View is the UI Layer, and the Controllers are the workflow objects in the Application layer.

                                                                                                                                                                                                                                                                                                                                                                此原则的合法放宽是 Observer 模式,其中域对象将消息发送到仅根据接口(如 PropertyListener(这种情况的常见 Java 接口))查看的 UI 对象。然后,域对象不知道 UI 对象是 UI 对象,它不知道它的具体 window 类。它只知道对象是实现 PropertyListener 接口的对象。

                                                                                                                                                                                                                                                                                                                                                                A legitimate relaxation of this principle is the Observer pattern, where the domain objects send messages to UI objects viewed only in terms of an interface such as PropertyListener (a common Java interface for this situation). Then, the domain object doesn't know that the UI object is a UI objectit doesn't know its concrete window class. It only knows the object as something that implements the PropertyListener interface.



                                                                                                                                                                                                                                                                                                                                                                该原则的另一部分是 domain classes 封装了与 application logic相关的信息和行为。窗口类相对较薄;它们负责输入和输出以及捕获 GUI 事件,但不维护应用程序数据或不直接提供应用程序逻辑。例如,Java JFrame 窗口不应具有执行税款计算的方法。Web JSP 页不应包含用于计算税款的逻辑。这些 UI 元素应委托给非 UI 元素来承担此类职责。

                                                                                                                                                                                                                                                                                                                                                                A further part of this principle is that the domain classes encapsulate the information and behavior related to application logic. The window classes are relatively thin; they are responsible for input and output, and catching GUI events, but do not maintain application data or directly provide application logic. For example, a Java JFrame window should not have a method that does a tax calculation. A Web JSP page should not contain logic to calculate the tax. These UI elements should delegate to non-UI elements for such responsibilities.

                                                                                                                                                                                                                                                                                                                                                                模型-视图分离的动机包括:

                                                                                                                                                                                                                                                                                                                                                                The motivation for Model-View Separation includes:

                                                                                                                                                                                                                                                                                                                                                                • 支持专注于域流程而不是用户界面的内聚模型定义。

                                                                                                                                                                                                                                                                                                                                                                • To support cohesive model definitions that focus on the domain processes, rather than on user interfaces.

                                                                                                                                                                                                                                                                                                                                                                • 允许单独开发模型层和用户界面层。

                                                                                                                                                                                                                                                                                                                                                                • To allow separate development of the model and user interface layers.

                                                                                                                                                                                                                                                                                                                                                                • 为了将接口中的需求更改对域层的影响降至最低。

                                                                                                                                                                                                                                                                                                                                                                • To minimize the impact of requirements changes in the interface upon the domain layer.

                                                                                                                                                                                                                                                                                                                                                                • 允许新视图轻松连接到现有域层,而不会影响域层。

                                                                                                                                                                                                                                                                                                                                                                • To allow new views to be easily connected to an existing domain layer, without affecting the domain layer.

                                                                                                                                                                                                                                                                                                                                                                • 允许在同一模型对象上同时显示多个视图,例如销售信息的表格视图和业务图表视图。

                                                                                                                                                                                                                                                                                                                                                                • To allow multiple simultaneous views on the same model object, such as both a tabular and business chart view of sales information.

                                                                                                                                                                                                                                                                                                                                                                • 允许独立于用户界面层执行模型层,例如在消息处理或批处理模式系统中。

                                                                                                                                                                                                                                                                                                                                                                • To allow execution of the model layer independent of the user interface layer, such as in a message-processing or batch-mode system.

                                                                                                                                                                                                                                                                                                                                                                • 允许将模型层轻松移植到另一个用户界面框架。

                                                                                                                                                                                                                                                                                                                                                                • To allow easy porting of the model layer to another user interface framework.

                                                                                                                                                                                                                                                                                                                                                                  13.8. SSD、系统操作和层之间有什么联系?

                                                                                                                                                                                                                                                                                                                                                                  13.8. What's the Connection Between SSDs, System Operations, and Layers?

                                                                                                                                                                                                                                                                                                                                                                  在分析工作期间,我们为用例场景绘制了一些 SSD。我们确定了从外部参与者到系统中的输入事件,调用了 makeNewSaleenterItem 等系统操作。

                                                                                                                                                                                                                                                                                                                                                                  During analysis work, we sketched some SSDs for use case scenarios. We identified input events from external actors into the system, calling upon system operations such as makeNewSale and enterItem.

                                                                                                                                                                                                                                                                                                                                                                  SSD 说明了这些系统操作,但隐藏了特定的 UI 对象。但是,通常捕获这些系统操作请求的将是系统 UI 层中的对象,通常使用富客户端 GUI 或 Web 页。

                                                                                                                                                                                                                                                                                                                                                                  The SSDs illustrate these system operations, but hide the specific UI objects. Nevertheless, normally it will be objects in the UI layer of the system that capture these system operation requests, usually with a rich client GUI or Web page.

                                                                                                                                                                                                                                                                                                                                                                  在支持高内聚和关注点分离的设计良好的分层架构中,UI 层对象会将请求从 UI 层转发或委托到域层进行处理。

                                                                                                                                                                                                                                                                                                                                                                  In a well-designed layered architecture that supports high cohesion and a separation of concerns, the UI layer objects will then forwardor delegatethe request from the UI layer onto the domain layer for handling.

                                                                                                                                                                                                                                                                                                                                                                  现在,关键点是:

                                                                                                                                                                                                                                                                                                                                                                  Now, here's the key point:

                                                                                                                                                                                                                                                                                                                                                                  从 UI 层发送到域层的消息将是 SSD 上显示的消息,例如 enterItem

                                                                                                                                                                                                                                                                                                                                                                  The messages sent from the UI layer to the domain layer will be the messages illustrated on the SSDs, such as enterItem.



                                                                                                                                                                                                                                                                                                                                                                  例如,在 Java Swing 中,UI 层中名为 ProcessSaleFrame 的 GUI 窗口类可能会选取请求输入项目的鼠标和键盘事件,然后 ProcessSaleFrame 对象会将 enterItem 消息发送到域层中的软件对象(如 Register)以执行应用程序逻辑。参见图 13.8

                                                                                                                                                                                                                                                                                                                                                                  For example, in Java Swing, perhaps a GUI window class called ProcessSaleFrame in the UI layer will pick up the mouse and keyboard events requesting to enter an item, and then the ProcessSaleFrame object will send an enterItem message on to a software object in the domain layer, such as Register, to perform the application logic. See Figure 13.8.

                                                                                                                                                                                                                                                                                                                                                                  图 13.8.SSD 和层中的系统操作。



                                                                                                                                                                                                                                                                                                                                                                    13.9. 示例:NextGen Logical Architecture 和 Package 图

                                                                                                                                                                                                                                                                                                                                                                    13.9. Example: NextGen Logical Architecture and Package Diagram

                                                                                                                                                                                                                                                                                                                                                                    图 13.2 暗示了这次迭代的简单逻辑架构。在以后的迭代中,事情变得更加有趣;例如,请参阅从第 559 页开始的 NextGen 逻辑架构和封装图的许多示例。

                                                                                                                                                                                                                                                                                                                                                                    Figure 13.2 hints at the simple logical architecture for this iteration. Things get more interesting in later iterations; for example, see many examples of the NextGen logical architecture and package diagrams starting on p. 559.

                                                                                                                                                                                                                                                                                                                                                                      13.10. 示例:垄断逻辑架构?

                                                                                                                                                                                                                                                                                                                                                                      13.10. Example: Monopoly Logical Architecture?

                                                                                                                                                                                                                                                                                                                                                                      Monopoly 架构是一个简单的分层设计 UI、域和服务。没有什么新奇的要说明的,因此 NextGen 案例研究用于架构示例。

                                                                                                                                                                                                                                                                                                                                                                      The Monopoly architecture is a simple layered designUI, domain, and services. There is nothing novel to illustrate, so the NextGen case study is used for the architectural examples.

                                                                                                                                                                                                                                                                                                                                                                        13.11. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                        13.11. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                        有大量关于分层体系结构的文献,包括印刷品和 Web 资料。Pattern Languages of Program Design, volume 1, [CS95] 中的一系列模式首先以模式形式解决了这个主题,尽管分层体系结构至少从 1960 年代就开始使用和撰写了相关文章;第 2 卷继续介绍更多与 Layers 相关的模式。面向模式的软件体系结构,第 1 卷 [BMRSS96] 提供了对 Layers 模式的良好处理。

                                                                                                                                                                                                                                                                                                                                                                        There's a wealth of literature on layered architectures, both in print and on the Web. A series of patterns in Pattern Languages of Program Design, volume 1, [CS95] first address the topic in pattern form, although layered architectures have been used and written about since at least the 1960s; volume 2 continues with further layers-related patterns. Pattern-Oriented Software Architecture, volume 1 [BMRSS96], provides a good treatment of the Layers pattern.

                                                                                                                                                                                                                                                                                                                                                                          第 14 章.转到 Object Design

                                                                                                                                                                                                                                                                                                                                                                          Chapter 14. On to Object Design

                                                                                                                                                                                                                                                                                                                                                                          我不喜欢'炸弹'这个词。它不是炸弹。这是一个正在爆炸的设备。

                                                                                                                                                                                                                                                                                                                                                                          雅克·勒布朗大使谈核“武器”

                                                                                                                                                                                                                                                                                                                                                                          I do not like this word 'bomb.' It is not a bomb. It is a device that is exploding.

                                                                                                                                                                                                                                                                                                                                                                          Ambassador Jacques le Blanc on nuclear 'weapons'

                                                                                                                                                                                                                                                                                                                                                                          目标

                                                                                                                                                                                                                                                                                                                                                                          Objectives

                                                                                                                                                                                                                                                                                                                                                                          • 了解动态和静态对象设计建模。

                                                                                                                                                                                                                                                                                                                                                                          • Understand dynamic and static object design modeling.

                                                                                                                                                                                                                                                                                                                                                                          • 尝试敏捷建模或用于绘图的 UML CASE 工具。

                                                                                                                                                                                                                                                                                                                                                                          • Try agile modeling, or a UML CASE tool for drawing.



                                                                                                                                                                                                                                                                                                                                                                            介绍

                                                                                                                                                                                                                                                                                                                                                                            Introduction

                                                                                                                                                                                                                                                                                                                                                                            开发人员如何设计对象?以下是三种方法:

                                                                                                                                                                                                                                                                                                                                                                            How do developers design objects? Here are three ways:

                                                                                                                                                                                                                                                                                                                                                                            1. 法典。边编码边设计(Java、C# 等),最好使用重构等强大工具。从心智模型到代码。

                                                                                                                                                                                                                                                                                                                                                                            2. Code. Design-while-coding (Java, C#, …), ideally with power tools such as refactorings. From mental model to code.

                                                                                                                                                                                                                                                                                                                                                                            3. 绘制,然后编码。在白板或 UML CASE 工具上绘制一些 UML,然后使用文本强 IDE(例如 Eclipse 或 Visual Studio)切换到 #1。

                                                                                                                                                                                                                                                                                                                                                                            4. Draw, then code. Drawing some UML on a whiteboard or UML CASE tool, then switching to #1 with a text-strong IDE (e.g., Eclipse or Visual Studio).

                                                                                                                                                                                                                                                                                                                                                                            5. 只平局。不知何故,该工具从图表中生成所有内容。许多死去的工具供应商已经冲到这个陡峭岛屿的海岸上。“Only draw” 用词不当,因为这仍然涉及附加到 UML 图形元素的文本编程语言。

                                                                                                                                                                                                                                                                                                                                                                            6. Only draw. Somehow, the tool generates everything from diagrams. Many a dead tool vendor has washed onto the shores of this steep island. "Only draw" is a misnomer, as this still involves a text programming language attached to UML graphic elements.

                                                                                                                                                                                                                                                                                                                                                                            当然,还有其他设计方法,使用其他 “语言”。[1] 如果我们使用 Draw,然后使用 code(UML 最流行的方法),那么绘制开销应该是值得的。本章在编码之前介绍对象设计和轻量级绘图,并建议使其获得回报的方法。

                                                                                                                                                                                                                                                                                                                                                                            Of course, there are other ways to design, with other "languages."[1] If we use Draw, then code (the most popular approach with UML), the drawing overhead should be worth the effort. This chapter introduces object design and lightweight drawing before coding, suggesting ways to make it pay off.

                                                                                                                                                                                                                                                                                                                                                                            [1] 什么是下一代语言?5GL?一种观点认为,它提高了编码符号的级别,从位到文本,再到图标(甚至手势),将更多功能打包到每个符号中。另一种观点认为 5GL 更具有声明性和目标指定性,而不是程序性,尽管 4GL 已经表现出了这一点。

                                                                                                                                                                                                                                                                                                                                                                            [1] What's a next-generation language? A 5GL? One view is that it's one that raises the level of the coding symbols, from bits to text to perhaps icons (or even gestures), packing more functionality into each symbol. Another view is that a 5GL is more declarative and goal-specifying rather than procedural, although 4GLs already exhibit this.



                                                                                                                                                                                                                                                                                                                                                                              14.1. 敏捷建模和轻量级 UML 绘图

                                                                                                                                                                                                                                                                                                                                                                              14.1. Agile Modeling and Lightweight UML Drawing

                                                                                                                                                                                                                                                                                                                                                                              敏捷建模 [Ambler02] 的一些目标是减少绘图开销建模以理解和交流,而不是记录,尽管使用数码照片进行记录很容易。尝试简单的敏捷建模方法。练习包括使用大量白板(一个房间十个,而不是两个)或特殊的白色塑料静电粘附板(像白板一样工作)覆盖大面积的墙壁区域,使用记号笔、数码相机和打印机来捕捉“UML 作为草图”,这是应用 UML 的三种方法之一 [Fowler03]。

                                                                                                                                                                                                                                                                                                                                                                              Some aims of agile modeling [Ambler02] are to reduce drawing overhead and model to understand and communicate, rather than to documentthough documenting is easy with digital photos. Try the simple agile modeling approach. Practices include using lots of whiteboards (ten in a room, not two) or special white plastic static cling sheets (that work like whiteboards) covering large wall areas, using markers, digital cameras, and printers to capture "UML as sketch"one of the three ways to apply UML [Fowler03].





                                                                                                                                                                                                                                                                                                                                                                              敏捷建模还包括

                                                                                                                                                                                                                                                                                                                                                                              Agile modeling also includes

                                                                                                                                                                                                                                                                                                                                                                              • 与他人一起建模

                                                                                                                                                                                                                                                                                                                                                                              • Modeling with others.

                                                                                                                                                                                                                                                                                                                                                                              • 并行创建多个模型。例如,在交互图墙上写 5 分钟,然后在相关类图墙上写 5 分钟。

                                                                                                                                                                                                                                                                                                                                                                              • Creating several models in parallel. For example, five minutes on a wall of interaction diagrams, then five minutes on a wall of related class diagrams.

                                                                                                                                                                                                                                                                                                                                                                              你想画的面积有多大?用你的眼睛和手?15 x 2 还是 50 x 40 厘米(更多显示器尺寸)?大多数人更喜欢大。但是,廉价的虚拟现实 UML 工具尚不存在。简单的替代方案是大量白色的静态粘附纸(或白板),这反映了 XP 的敏捷原则:做可能奏效的最简单的事情

                                                                                                                                                                                                                                                                                                                                                                              How big is the area you'd like to draw in? With your eyes and hands? Fifteen by two meters or 50 by 40 cm. (more monitor size)? Most people prefer big. But cheap virtual reality UML tools don't exist, yet. The simple alternative is lots of white static cling sheets (or whiteboards), reflecting the XP agile principle: Do the simplest thing that could possibly work.

                                                                                                                                                                                                                                                                                                                                                                              更多提示:

                                                                                                                                                                                                                                                                                                                                                                              More tips:

                                                                                                                                                                                                                                                                                                                                                                              • 将墙图的数码照片上传到内部 Wiki(请参阅 www.twiki.org)很容易,该 Wiki 可捕获您的项目信息。

                                                                                                                                                                                                                                                                                                                                                                              • It's easy to upload digital photos of wall drawings to an internal wiki (see www.twiki.org) that captures your project information.

                                                                                                                                                                                                                                                                                                                                                                              • 白色塑料防静电贴膜热门品牌:

                                                                                                                                                                                                                                                                                                                                                                                • 北美(和...):Avery Write-On 保鲜纸。

                                                                                                                                                                                                                                                                                                                                                                                • 欧洲:Legamaster 魔术图。[2]

                                                                                                                                                                                                                                                                                                                                                                                  [2] 我喜欢这种滚动样式;它使展开一张长长的保鲜塑料变得容易。

                                                                                                                                                                                                                                                                                                                                                                              • Popular brands of white plastic static cling sheets:

                                                                                                                                                                                                                                                                                                                                                                                • North America (and …): Avery Write-On Cling Sheets.

                                                                                                                                                                                                                                                                                                                                                                                • Europe: Legamaster Magic-Chart.[2]

                                                                                                                                                                                                                                                                                                                                                                                  [2] I like this roll style; it makes it easy to unroll a long sheet of cling-plastic.

                                                                                                                                                                                                                                                                                                                                                                                14.2. UML CASE 工具

                                                                                                                                                                                                                                                                                                                                                                                14.2. UML CASE Tools

                                                                                                                                                                                                                                                                                                                                                                                请不要将我关于墙面草图和敏捷建模的建议误解为暗示 UML CASE 工具也没有用。两者都可以增加价值。这些工具从昂贵的到免费的和开源的,并且每年的实用性都在提高。每年的最佳选择都会发生变化,所以我不会提出过时的建议,但是......

                                                                                                                                                                                                                                                                                                                                                                                Please don't misinterpret my suggestion of wall-sketching and agile modeling as implying that UML CASE tools aren't also useful. Both can add value. These tools range from expensive to free and open source, and each year improve in usefulness. Each year's best choice changes, so I won't make a stale suggestion, but…

                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                Guidelines

                                                                                                                                                                                                                                                                                                                                                                                • 选择与流行的文本强 IDE(如 Eclipse 或 Visual Studio)集成的 UML CASE 工具。

                                                                                                                                                                                                                                                                                                                                                                                • Choose a UML CASE tool that integrates with popular text-strong IDEs, such as Eclipse or Visual Studio.

                                                                                                                                                                                                                                                                                                                                                                                • 选择一个 UML 工具,该工具不仅可以对类图(常见)进行逆向工程(从代码生成图),还可以对交互图(更罕见,但对于了解程序的调用流结构非常有用)进行逆向工程。

                                                                                                                                                                                                                                                                                                                                                                                • Choose a UML tool that can reverse-engineer (generate diagrams from code) not only class diagrams (common), but also interaction diagrams (more rare, but very useful to learn call-flow structure of a program).



                                                                                                                                                                                                                                                                                                                                                                                许多开发人员发现,在他们最喜欢的 IDE 中编写代码片刻,然后按下一个按钮,对代码进行逆向工程,并查看他们设计的 UML 大图图形视图非常有用。

                                                                                                                                                                                                                                                                                                                                                                                Many developers find it useful to code awhile in their favorite IDE, then press a button, reverse-engineer the code, and see a UML big-picture graphical view of their design.

                                                                                                                                                                                                                                                                                                                                                                                另外,请注意:

                                                                                                                                                                                                                                                                                                                                                                                Also, note:

                                                                                                                                                                                                                                                                                                                                                                                在墙壁上进行敏捷建模和使用 集成到文本强 IDE 中的 UML CASE 工具可以起到补充作用。在活动的不同阶段尝试这两种方法。

                                                                                                                                                                                                                                                                                                                                                                                Agile modeling on the walls and using a UML CASE tool integrated into a text-strong IDE can be complementary. Try both during different phases of activity.



                                                                                                                                                                                                                                                                                                                                                                                  14.3. 在编码之前绘制 UML 花了多少时间?

                                                                                                                                                                                                                                                                                                                                                                                  14.3. How Much Time Spent Drawing UML Before Coding?

                                                                                                                                                                                                                                                                                                                                                                                  指引

                                                                                                                                                                                                                                                                                                                                                                                  Guideline

                                                                                                                                                                                                                                                                                                                                                                                  对于为期三周的有时间限制的迭代,在迭代开始时,花几个小时或最多一天(与合作伙伴一起)在迭代开始时“在墙壁上”(或使用 UML CASE 工具)为详细对象设计的困难、创造性部分绘制 UML。然后停下来,如果绘制草图,也许可以拍一些数码照片,打印照片,并在迭代的剩余部分过渡到编码,以 UML 图纸为灵感作为起点,但要认识到代码中的最终设计会有所不同和改进。在整个迭代过程中,可能会发生较短的绘图/草绘会话。

                                                                                                                                                                                                                                                                                                                                                                                  For a three-week timeboxed iteration, spend a few hours or at most one day (with partners) near the start of the iteration "at the walls" (or with a UML CASE tool) drawing UML for the hard, creative parts of the detailed object design. Then stopand if sketchingperhaps take digital photos, print the pictures, and transition to coding for the remainder of the iteration, using the UML drawings for inspiration as a starting point, but recognizing that the final design in code will diverge and improve. Shorter drawing/sketching sessions may occur throughout the iteration.



                                                                                                                                                                                                                                                                                                                                                                                  如果是敏捷建模,那么在每次后续建模会话之前,将不断增长的代码库逆向工程为 UML 图,将它们打印出来(可能在大型绘图仪纸上),并在草绘会话期间引用它们。

                                                                                                                                                                                                                                                                                                                                                                                  If agile modeling, then before each subsequent modeling session, reverse-engineer the growing code base into UML diagrams, print them out (perhaps on large plotter paper), and refer to them during the sketching session.

                                                                                                                                                                                                                                                                                                                                                                                    14.4. 设计对象:什么是静态和动态建模?

                                                                                                                                                                                                                                                                                                                                                                                    14.4. Designing Objects: What are Static and Dynamic Modeling?

                                                                                                                                                                                                                                                                                                                                                                                    有两种类型的对象模型:动态和静态。动态模型,如 UML 交互图(序列图通信图),有助于设计逻辑、代码行为或方法体。它们往往是创建更有趣、更难、更重要的图表。静态模型(如 UML 类图)有助于设计包、类名、特性和方法签名(但不是方法体)的定义。参见图 14.1

                                                                                                                                                                                                                                                                                                                                                                                    There are two kinds of object models: dynamic and static. Dynamic models, such as UML interaction diagrams (sequence diagrams or communication diagrams), help design the logic, the behavior of the code or the method bodies. They tend to be the more interesting, difficult, important diagrams to create. Static models, such as UML class diagrams, help design the definition of packages, class names, attributes, and method signatures (but not method bodies). See Figure 14.1.

                                                                                                                                                                                                                                                                                                                                                                                    图 14.1.用于对象建模的静态和动态 UML 图。



                                                                                                                                                                                                                                                                                                                                                                                    静态和动态建模与并行创建模型的敏捷建模实践之间存在关系:在交互图(动态)上花费一小段时间,然后切换到相关类图(静态)的墙。

                                                                                                                                                                                                                                                                                                                                                                                    There's a relationship between static and dynamic modeling and the agile modeling practice of create models in parallel: Spend a short period of time on interaction diagrams (dynamics), then switch to a wall of related class diagrams (statics).

                                                                                                                                                                                                                                                                                                                                                                                    动态对象建模

                                                                                                                                                                                                                                                                                                                                                                                    Dynamic Object Modeling

                                                                                                                                                                                                                                                                                                                                                                                    刚接触 UML 的人往往认为重要的图是静态视图类图,但实际上,大多数具有挑战性、有趣、有用的设计工作都是在绘制 UML 动态视图交互图时进行的。正是在动态对象建模(例如绘制序列图)期间,“橡胶上路”才真正考虑了需要存在哪些对象的确切细节以及它们如何通过消息和方法进行协作。

                                                                                                                                                                                                                                                                                                                                                                                    People new to UML tend to think that the important diagram is the static-view class diagram, but in fact, most of the challenging, interesting, useful design work happens while drawing the UML dynamic-view interaction diagrams. It's during dynamic object modeling (such as drawing sequence diagrams) that "the rubber hits the road" in terms of really thinking through the exact details of what objects need to exist and how they collaborate via messages and methods.

                                                                                                                                                                                                                                                                                                                                                                                    因此,本书首先介绍使用交互图进行动态对象建模。

                                                                                                                                                                                                                                                                                                                                                                                    Therefore, this book starts by introducing dynamic object modeling with interaction diagrams.



                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                    花费大量时间制作交互图(序列图或通信图),而不仅仅是类图。

                                                                                                                                                                                                                                                                                                                                                                                    Spend significant time doing interaction diagrams (sequence or communication diagrams), not just class diagrams.

                                                                                                                                                                                                                                                                                                                                                                                    忽略此准则是 UML 中非常常见的最坏做法。

                                                                                                                                                                                                                                                                                                                                                                                    Ignoring this guideline is a very common worst-practice with UML.



                                                                                                                                                                                                                                                                                                                                                                                    请注意,尤其是在动态建模期间,我们应用了责任驱动设计和 GRASP 原则。后续章节重点介绍本书的这些关键主题和 OO 设计中的关键技能。

                                                                                                                                                                                                                                                                                                                                                                                    Note that it's especially during dynamic modeling that we apply responsibility-driven design and the GRASP principles. The subsequent chapters focus on these key topics of the bookand key skills in OO design.



                                                                                                                                                                                                                                                                                                                                                                                    UML 工具包中还有其他动态工具,包括状态机图(第 485 页)和活动(第 477 页)。

                                                                                                                                                                                                                                                                                                                                                                                    There are other dynamic tools in the UML kit, including state machine diagrams (p. 485) and activity diagrams (p. 477).

                                                                                                                                                                                                                                                                                                                                                                                    静态对象建模

                                                                                                                                                                                                                                                                                                                                                                                    Static Object Modeling

                                                                                                                                                                                                                                                                                                                                                                                    最常见的静态对象建模是使用 UML 类图。在首先介绍使用交互图进行动态建模之后,我将介绍详细信息。但请注意,如果开发人员正在应用并行创建多个模型的敏捷建模实践,他们将同时绘制交互图和类图。

                                                                                                                                                                                                                                                                                                                                                                                    The most common static object modeling is with UML class diagrams. After first covering dynamic modeling with interaction diagrams, I introduce the details. Note, though, that if the developers are applying the agile modeling practice of Create several models in parallel, they will be drawing both interaction and class diagrams concurrently.



                                                                                                                                                                                                                                                                                                                                                                                    UML 中对静态建模的其他支持包括包图(第 197 页)和部署图(第 621 页)。

                                                                                                                                                                                                                                                                                                                                                                                    Other support in the UML for static modeling includes package diagrams (p. 197) and deployment diagrams (p. 621).

                                                                                                                                                                                                                                                                                                                                                                                      14.5. 对象设计技能相对于 UML 表示法技能的重要性

                                                                                                                                                                                                                                                                                                                                                                                      14.5. The Importance of Object Design Skill over UML Notation Skill

                                                                                                                                                                                                                                                                                                                                                                                      以下各章探讨了应用 UML 图时的详细对象设计。前面已经说过了,但需要强调的是:重要的是要知道如何在对象中思考和设计,并应用对象设计最佳实践模式,这是一项与了解 UML 表示法截然不同且更有价值的技能。

                                                                                                                                                                                                                                                                                                                                                                                      The following chapters explore detailed object design while applying UML diagrams. It's been said before, but is important to stress: What's important is knowing how to think and design in objects, and apply object design best-practice patterns, which is a very different and much more valuable skill than knowing UML notation.

                                                                                                                                                                                                                                                                                                                                                                                      在绘制 UML 对象图时,我们需要回答关键问题:对象的职责是什么?它与谁合作?应该应用哪些设计模式?这比了解 UML 1.4 和 2.0 表示法之间的区别重要得多!因此,以下章节的重点是对象设计中的这些原则和模式。

                                                                                                                                                                                                                                                                                                                                                                                      While drawing a UML object diagram, we need to answer key questions: What are the responsibilities of the object? Who does it collaborate with? What design patterns should be applied? Far more important than knowing the difference between UML 1.4 and 2.0 notation! Therefore, the emphasis of the following chapters is on these principles and patterns in object design.

                                                                                                                                                                                                                                                                                                                                                                                      对象设计技能与 UML 表示法技能

                                                                                                                                                                                                                                                                                                                                                                                      Object Design Skill vs. UML Notation Skill

                                                                                                                                                                                                                                                                                                                                                                                      绘制 UML 反映了对设计做出决策。

                                                                                                                                                                                                                                                                                                                                                                                      Drawing UML is a reflection of making decisions about the design.

                                                                                                                                                                                                                                                                                                                                                                                      对象设计技能才是最重要的,不知道如何绘制 UML。基本对象设计需要了解:

                                                                                                                                                                                                                                                                                                                                                                                      The object design skills are what matter, not knowing how to draw UML. Fundamental object design requires knowledge of:

                                                                                                                                                                                                                                                                                                                                                                                      • 责任分配原则

                                                                                                                                                                                                                                                                                                                                                                                      • principles of responsibility assignment

                                                                                                                                                                                                                                                                                                                                                                                      • 设计模式

                                                                                                                                                                                                                                                                                                                                                                                      • design patterns



                                                                                                                                                                                                                                                                                                                                                                                        14.6. 其他对象设计技术:CRC 卡

                                                                                                                                                                                                                                                                                                                                                                                        14.6. Other Object Design Techniques: CRC Cards

                                                                                                                                                                                                                                                                                                                                                                                        人们喜欢不同的设计方法,因为熟悉度,而且相当重要的是,因为不同的认知风格。不要假设图标和图片对每个人来说都比文本更好,反之亦然。

                                                                                                                                                                                                                                                                                                                                                                                        People prefer different design methods because of familiarity and, quite significantly, because of different cognitive styles. Don't assume that icons and pictures are better than text for everyone, or vice versa.

                                                                                                                                                                                                                                                                                                                                                                                        一种流行的面向文本的建模技术是类责任协作 (CRC) 卡,它由敏捷、有影响力的 Kent Beck 和 Ward Cunningham(也是 XP 和设计模式思想的创始人)创建。

                                                                                                                                                                                                                                                                                                                                                                                        A popular text-oriented modeling technique is Class Responsibility Collaboration (CRC) cards, created by the agile, influential minds of Kent Beck and Ward Cunningham (also founders of the ideas of XP and design patterns).

                                                                                                                                                                                                                                                                                                                                                                                        CRC 卡是纸质索引卡,上面写着班级的职责和合作者。每张卡片代表一个类。CRC 建模会话涉及一组人围坐在桌子旁,讨论并在卡片上写下,同时他们与对象玩“假设”场景,考虑他们必须做什么以及他们必须与哪些其他对象协作。参见图 14.2图 14.3

                                                                                                                                                                                                                                                                                                                                                                                        CRC cards are paper index cards on which one writes the responsibilities and collaborators of classes. Each card represents one class. A CRC modeling session involves a group sitting around a table, discussing and writing on the cards as they play "what if" scenarios with the objects, considering what they must do and what other objects they must collaborate with. See Figure 14.2 and Figure 14.3.

                                                                                                                                                                                                                                                                                                                                                                                        图 14.2.CRC 卡的模板。



                                                                                                                                                                                                                                                                                                                                                                                        图 14.3.四个示例 CRC 卡。这个最小化的示例仅用于显示典型的细节级别,而不是特定的文本。



                                                                                                                                                                                                                                                                                                                                                                                          第 15 章.UML 交互图

                                                                                                                                                                                                                                                                                                                                                                                          Chapter 15. UML Interaction Diagrams

                                                                                                                                                                                                                                                                                                                                                                                          猫比狗聪明。你不能让八只猫拉着雪橇穿过雪地。

                                                                                                                                                                                                                                                                                                                                                                                          杰夫·瓦尔迪兹

                                                                                                                                                                                                                                                                                                                                                                                          Cats are smarter than dogs. You can't get eight cats to pull a sled through snow.

                                                                                                                                                                                                                                                                                                                                                                                          Jeff Valdez

                                                                                                                                                                                                                                                                                                                                                                                          目标

                                                                                                                                                                                                                                                                                                                                                                                          Objectives

                                                                                                                                                                                                                                                                                                                                                                                          • 为常用的 UML 交互图、符号序列和通信图提供参考。

                                                                                                                                                                                                                                                                                                                                                                                          • Provide a reference for frequently used UML interaction diagram notationsequence and communication diagrams.



                                                                                                                                                                                                                                                                                                                                                                                            介绍

                                                                                                                                                                                                                                                                                                                                                                                            Introduction

                                                                                                                                                                                                                                                                                                                                                                                            UML 包括交互图,用于说明对象如何通过消息进行交互。它们用于动态对象建模。有两种常见类型:序列图和通信交互图。本章介绍了符号,将其视为略读的参考,而后续章节则侧重于一个更重要的问题:OO 设计中的关键原则是什么?

                                                                                                                                                                                                                                                                                                                                                                                            The UML includes interaction diagrams to illustrate how objects interact via messages. They are used for dynamic object modeling. There are two common types: sequence and communication interaction diagrams. This chapter introduces the notationview it as a reference to skim throughwhile subsequent chapters focus on a more important question: What are key principles in OO design?

                                                                                                                                                                                                                                                                                                                                                                                            在以下章节中,将应用交互图来帮助解释和演示对象设计。因此,在继续之前至少浏览这些示例是有用的。

                                                                                                                                                                                                                                                                                                                                                                                            In the following chapters, interaction diagrams are applied to help explain and demonstrate object design. Hence, it's useful to at least skim these examples before moving on.

                                                                                                                                                                                                                                                                                                                                                                                              15.1. 序列图和通信图

                                                                                                                                                                                                                                                                                                                                                                                              15.1. Sequence and Communication Diagrams

                                                                                                                                                                                                                                                                                                                                                                                              术语交互图是两种更专业的 UML 图类型的泛化:

                                                                                                                                                                                                                                                                                                                                                                                              The term interaction diagram is a generalization of two more specialized UML diagram types:

                                                                                                                                                                                                                                                                                                                                                                                              • 序列图

                                                                                                                                                                                                                                                                                                                                                                                              • sequence diagrams

                                                                                                                                                                                                                                                                                                                                                                                              • 通信图

                                                                                                                                                                                                                                                                                                                                                                                              • communication diagrams

                                                                                                                                                                                                                                                                                                                                                                                              两者都可以表达类似的交互。

                                                                                                                                                                                                                                                                                                                                                                                              Both can express similar interactions.

                                                                                                                                                                                                                                                                                                                                                                                              相关图是交互概览图;它提供了一组交互图在 logic 和 process-flow 方面如何关联的大局概述。但是,它是 UML 2 的新功能,因此现在判断它是否会真正有用还为时过早。

                                                                                                                                                                                                                                                                                                                                                                                              A related diagram is the interaction overview diagram; it provides a big-picture overview of how a set of interaction diagrams are related in terms of logic and process-flow. However, it's new to UML 2, and so it's too early to tell if it will be practically useful.

                                                                                                                                                                                                                                                                                                                                                                                              序列图是两种类型中符号更丰富的一种,但通信图也有其用途,尤其是用于墙面素描。在整本书中,这两种类型都将用于强调选择的灵活性。

                                                                                                                                                                                                                                                                                                                                                                                              Sequence diagrams are the more notationally rich of the two types, but communication diagrams have their use as well, especially for wall sketching. Throughout the book, both types will be used to emphasize the flexibility in choice.

                                                                                                                                                                                                                                                                                                                                                                                              序列图以一种栅栏格式说明了交互,其中每个新对象都添加到右侧,如图 15.1 所示。

                                                                                                                                                                                                                                                                                                                                                                                              Sequence diagrams illustrate interactions in a kind of fence format, in which each new object is added to the right, as shown in Figure 15.1.

                                                                                                                                                                                                                                                                                                                                                                                              图 15.1.序列图。



                                                                                                                                                                                                                                                                                                                                                                                              这在代码中可能表示什么?[1] 该类 A 可能具有一个名为 doOne 的方法和一个类型 B 的属性。此外,该类 B 具有名为 doTwodoThree 的方法。也许 A 类的部分定义是:

                                                                                                                                                                                                                                                                                                                                                                                              What might this represent in code?[1] Probably, that class A has a method named doOne and an attribute of type B. Also, that class B has methods named doTwo and doThree. Perhaps the partial definition of class A is:

                                                                                                                                                                                                                                                                                                                                                                                              [1] 代码映射或生成规则会因 OO 语言而异

                                                                                                                                                                                                                                                                                                                                                                                              [1] Code mapping or generation rules will vary depending on the OO language

                                                                                                                                                                                                                                                                                                                                                                                              public class A
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                              private B myB = new B();
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public void doOne()
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                 myB.doTwo();
                                                                                                                                                                                                                                                                                                                                                                                                 myB.doThree();
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public class A
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                              private B myB = new B();
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public void doOne()
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                 myB.doTwo();
                                                                                                                                                                                                                                                                                                                                                                                                 myB.doThree();
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                              通信图以图形或网络格式说明对象交互,其中对象可以放置在图表上的任何位置(其墙壁素描优势的本质),如图 15.2 所示。

                                                                                                                                                                                                                                                                                                                                                                                              Communication diagrams illustrate object interactions in a graph or network format, in which objects can be placed anywhere on the diagram (the essence of their wall sketching advantage), as shown in Figure 15.2.

                                                                                                                                                                                                                                                                                                                                                                                              图 15.2.通信图。



                                                                                                                                                                                                                                                                                                                                                                                              序列图与通信图的优缺点是什么?

                                                                                                                                                                                                                                                                                                                                                                                              What are the Strengths and Weaknesses of Sequence vs. Communication Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                              每种图表类型都有优点,建模者有独特的偏好没有绝对“正确”的选择。但是,UML 工具通常强调序列图,因为它们具有更强的符号功能。

                                                                                                                                                                                                                                                                                                                                                                                              Each diagram type has advantages, and modelers have idiosyncratic preferencethere isn't an absolutely "correct" choice. However, UML tools usually emphasize sequence diagrams, because of their greater notational power.

                                                                                                                                                                                                                                                                                                                                                                                              序列图比通信图具有一些优势。也许首先,UML 规范更以序列图为中心,在符号和语义上投入了更多的思想和精力。因此,工具支持更好,并且有更多的符号选项可用。此外,使用序列图更容易查看呼叫流序列只需从上到下阅读即可。对于通信图,我们必须读取序列号,例如“1:”和“2:”。因此,序列图非常适合用于文档编制或轻松读取使用 UML 工具从源代码生成的逆向工程调用流序列。

                                                                                                                                                                                                                                                                                                                                                                                              Sequence diagrams have some advantages over communication diagrams. Perhaps first and foremost, the UML specification is more sequence diagram centricmore thought and effort has been put into the notation and semantics. Thus, tool support is better and more notation options are available. Also, it is easier to see the call-flow sequence with sequence diagramssimply read top to bottom. With communication diagrams we must read the sequence numbers, such as "1:" and "2:". Hence, sequence diagrams are excellent for documentation or to easily read a reverse-engineered call-flow sequence, generated from source code with a UML tool.

                                                                                                                                                                                                                                                                                                                                                                                              但另一方面,通信图在应用“UML 作为草图”在墙壁上绘图(一种敏捷建模实践)时具有优势,因为它们更节省空间。这是因为这些框可以很容易地放置在或擦除水平或垂直的任何地方。因此,使用通信图修改墙壁草图也更容易。(在创造性的高变化 OO 设计工作中)在一个位置擦除一个盒子,在其他地方绘制一个新的盒子,然后为其画一条线是很简单的。相反,序列图中的新对象必须始终添加到右边缘,这是有限制的,因为它会迅速消耗和耗尽页面(或墙壁)上的右边缘空间;垂直维度中的可用空间未得到有效利用。与通信图形成对比,在墙上制作序列图的开发人员很快就会感受到绘制的痛苦。

                                                                                                                                                                                                                                                                                                                                                                                              But on the other hand, communication diagrams have advantages when applying "UML as sketch" to draw on walls (an Agile Modeling practice) because they are much more space-efficient. This is because the boxes can be easily placed or erased anywherehorizontal or vertical. Consequently as well, modifying wall sketches is easier with communication diagramsit is simple (during creative high-change OO design work) to erase a box at one location, draw a new one elsewhere, and sketch a line to it. In contrast, new objects in a sequence diagrams must always be added to the right edge, which is limiting as it quickly consumes and exhausts right-edge space on a page (or wall); free space in the vertical dimension is not efficiently used. Developers doing sequence diagrams on walls rapidly feel the drawing pain when contrasted with communication diagrams.



                                                                                                                                                                                                                                                                                                                                                                                              同样,当绘制要在窄页面上发布的图表时(如本书),通信图比序列图具有优势,它允许新对象的垂直扩展,可以将更多内容打包到一个小的视觉空间中。

                                                                                                                                                                                                                                                                                                                                                                                              Likewise, when drawing diagrams that are to be published on narrow pages (like this book), communication diagrams have the advantage over sequence diagrams of allowing vertical expansion for new objectsmuch more can be packed into a small visual space.

                                                                                                                                                                                                                                                                                                                                                                                              类型

                                                                                                                                                                                                                                                                                                                                                                                              Type

                                                                                                                                                                                                                                                                                                                                                                                              优势

                                                                                                                                                                                                                                                                                                                                                                                              Strengths

                                                                                                                                                                                                                                                                                                                                                                                              弱点

                                                                                                                                                                                                                                                                                                                                                                                              Weaknesses

                                                                                                                                                                                                                                                                                                                                                                                              序列

                                                                                                                                                                                                                                                                                                                                                                                              sequence

                                                                                                                                                                                                                                                                                                                                                                                              清楚地显示消息的顺序或时间顺序

                                                                                                                                                                                                                                                                                                                                                                                              clearly shows sequence or time ordering of messages

                                                                                                                                                                                                                                                                                                                                                                                              大量详细符号选项

                                                                                                                                                                                                                                                                                                                                                                                              large set of detailed notation options

                                                                                                                                                                                                                                                                                                                                                                                              添加新对象时强制向右扩展;占用水平空间

                                                                                                                                                                                                                                                                                                                                                                                              forced to extend to the right when adding new objects; consumes horizontal space

                                                                                                                                                                                                                                                                                                                                                                                              通信

                                                                                                                                                                                                                                                                                                                                                                                              communication

                                                                                                                                                                                                                                                                                                                                                                                              空间经济灵活地在二维中添加新对象

                                                                                                                                                                                                                                                                                                                                                                                              space economicalflexibility to add new objects in two dimensions

                                                                                                                                                                                                                                                                                                                                                                                              更难看到消息序列

                                                                                                                                                                                                                                                                                                                                                                                              more difficult to see sequence of messages

                                                                                                                                                                                                                                                                                                                                                                                              更少的 Notation 选项

                                                                                                                                                                                                                                                                                                                                                                                              fewer notation options



                                                                                                                                                                                                                                                                                                                                                                                              示例序列图:makePayment

                                                                                                                                                                                                                                                                                                                                                                                              Example Sequence Diagram: makePayment

                                                                                                                                                                                                                                                                                                                                                                                              图 15.3 所示的序列图如下所示:

                                                                                                                                                                                                                                                                                                                                                                                              The sequence diagram shown in Figure 15.3 is read as follows:

                                                                                                                                                                                                                                                                                                                                                                                              1. 消息 makePayment 被发送到 Register 的实例。无法识别发件人。

                                                                                                                                                                                                                                                                                                                                                                                              2. The message makePayment is sent to an instance of a Register. The sender is not identified.

                                                                                                                                                                                                                                                                                                                                                                                              3. Register 实例将 makePayment 消息发送到 Sale 实例。

                                                                                                                                                                                                                                                                                                                                                                                              4. The Register instance sends the makePayment message to a Sale instance.

                                                                                                                                                                                                                                                                                                                                                                                              5. Sale 实例创建 Payment 的实例。

                                                                                                                                                                                                                                                                                                                                                                                              6. The Sale instance creates an instance of a Payment.

                                                                                                                                                                                                                                                                                                                                                                                              图 15.3.序列图。



                                                                                                                                                                                                                                                                                                                                                                                              通过阅读图 15.3,Sale 类及其 makePayment 方法的相关代码可能是什么?

                                                                                                                                                                                                                                                                                                                                                                                              From reading Figure 15.3, what might be some related code for the Sale class and its makePayment method?

                                                                                                                                                                                                                                                                                                                                                                                              public class Sale
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                              private Payment payment;
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                 payment = new Payment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                 //…
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public class Sale
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                              private Payment payment;
                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                              public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                 payment = new Payment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                 //…
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                              示例通信图:makePayment

                                                                                                                                                                                                                                                                                                                                                                                              Example Communication Diagram: makePayment

                                                                                                                                                                                                                                                                                                                                                                                              图 15.4.通信图。



                                                                                                                                                                                                                                                                                                                                                                                              图 15.3 中所示的通信图与前面的序列图具有相同的意图。

                                                                                                                                                                                                                                                                                                                                                                                              The communication diagram shown in Figure 15.3 has the same intent as the prior sequence diagram.

                                                                                                                                                                                                                                                                                                                                                                                                15.2. UML 建模新手对交互图的关注不够!

                                                                                                                                                                                                                                                                                                                                                                                                15.2. Novice UML Modelers Don't Pay Enough Attention to Interaction Diagrams!

                                                                                                                                                                                                                                                                                                                                                                                                大多数 UML 新手都知道类图,并且通常认为它们是 OO 设计中唯一重要的图。不对!

                                                                                                                                                                                                                                                                                                                                                                                                Most UML novices are aware of class diagrams and usually think they are the only important diagram in OO design. Not true!

                                                                                                                                                                                                                                                                                                                                                                                                尽管静态视图类图确实很有用,但动态视图交互图或者更准确地说,动态交互建模的行为非常有价值。

                                                                                                                                                                                                                                                                                                                                                                                                Although the static-view class diagrams are indeed useful, the dynamic-view interaction diagramsor more precisely, acts of dynamic interaction modelingare incredibly valuable.

                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                花时间使用交互图进行动态对象建模,而不仅仅是使用类图进行静态对象建模。

                                                                                                                                                                                                                                                                                                                                                                                                Spend time doing dynamic object modeling with interaction diagrams, not just static object modeling with class diagrams.



                                                                                                                                                                                                                                                                                                                                                                                                为什么?因为当我们必须考虑要发送哪些消息、向谁发送以及以什么顺序发送的具体细节时,“橡胶上路”才能在思考真正的 OO 设计细节方面发挥作用。

                                                                                                                                                                                                                                                                                                                                                                                                Why? Because it's when we have to think through the concrete details of what messages to send, and to whom, and in what order, that the "rubber hits the road" in terms of thinking through the true OO design details.

                                                                                                                                                                                                                                                                                                                                                                                                  15.3. 常见的 UML 交互图表示法

                                                                                                                                                                                                                                                                                                                                                                                                  15.3. Common UML Interaction Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                  用 Lifeline Boxes 说明参与者

                                                                                                                                                                                                                                                                                                                                                                                                  Illustrating Participants with Lifeline Boxes

                                                                                                                                                                                                                                                                                                                                                                                                  在 UML 中,您在前面的示例交互图中看到的框称为 lifeline box。它们的精确 UML 定义很微妙,但非正式地它们代表了在某些结构图(如类图)的上下文中定义的交互相关部分的参与者。说 Lifeline Box 等于一个类的实例并不完全准确,但从非正式和实际的角度来看,参与者通常会被解释为这样。因此,在本文中,我经常会写类似 “the lifeline representing a Sale instance” 之类的内容,作为方便的速记。有关符号的常见情况,请参见图 15.5

                                                                                                                                                                                                                                                                                                                                                                                                  In the UML, the boxes you've seen in the prior sample interaction diagrams are called lifeline boxes. Their precise UML definition is subtle, but informally they represent the participants in the interactionrelated parts defined in the context of some structure diagram, such as a class diagram. It is not precisely accurate to say that a lifeline box equals an instance of a class, but informally and practically, the participants will often be interpreted as such. Therefore, in this text I'll often write something like "the lifeline representing a Sale instance," as a convenient shorthand. See Figure 15.5 for common cases of notation.

                                                                                                                                                                                                                                                                                                                                                                                                  图 15.5.用于显示交互参与者的生命线框。



                                                                                                                                                                                                                                                                                                                                                                                                  基本消息表达式语法

                                                                                                                                                                                                                                                                                                                                                                                                  Basic Message Expression Syntax

                                                                                                                                                                                                                                                                                                                                                                                                  交互图显示对象之间的消息;UML 具有这些消息表达式的标准语法:[2]

                                                                                                                                                                                                                                                                                                                                                                                                  Interaction diagrams show messages between objects; the UML has a standard syntax for these message expressions:[2]

                                                                                                                                                                                                                                                                                                                                                                                                  [2] UML 工具可以接受并支持 C# 或 Java 等替代语法。

                                                                                                                                                                                                                                                                                                                                                                                                  [2] An alternate syntax, such as C# or Java, is acceptableand supported by UML tools.

                                                                                                                                                                                                                                                                                                                                                                                                  return = message(parameter : parameterType) : returnType
                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                  return = message(parameter : parameterType) : returnType
                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                  如果没有参数,通常会排除括号,但仍然合法。

                                                                                                                                                                                                                                                                                                                                                                                                  Parentheses are usually excluded if there are no parameters, though still legal.

                                                                                                                                                                                                                                                                                                                                                                                                  如果类型信息明显或不重要,则可以排除该信息。

                                                                                                                                                                                                                                                                                                                                                                                                  Type information may be excluded if obvious or unimportant.

                                                                                                                                                                                                                                                                                                                                                                                                  例如:

                                                                                                                                                                                                                                                                                                                                                                                                  For example:

                                                                                                                                                                                                                                                                                                                                                                                                  initialize(code)
                                                                                                                                                                                                                                                                                                                                                                                                  initialize
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id)
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id:ItemID)
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id:ItemID) : ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                  initialize(code)
                                                                                                                                                                                                                                                                                                                                                                                                  initialize
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id)
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id:ItemID)
                                                                                                                                                                                                                                                                                                                                                                                                  d = getProductDescription(id:ItemID) : ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                  Singleton 对象

                                                                                                                                                                                                                                                                                                                                                                                                  Singleton Objects

                                                                                                                                                                                                                                                                                                                                                                                                  在 OO 设计模式的世界中,有一种模式特别常见,称为 Singleton 模式。稍后将对此进行解释,但该模式的含义是 instantiatednever two 类只有一个实例。换句话说,它是一个 “singleton” 实例。在 UML 交互图(序列或通信)中,这样的对象在生命线框的右上角标有 '1'。这意味着 Singleton 模式用于获得对象的可见性,其含义目前尚不清楚,但将在阅读第 442 页的描述时了解。参见图 15.6

                                                                                                                                                                                                                                                                                                                                                                                                  In the world of OO design patterns, there is one that is especially common, called the Singleton pattern. It is explained later, but an implication of the pattern is that there is only one instance of a class instantiatednever two. In other words, it is a "singleton" instance. In a UML interaction diagram (sequence or communication), such an object is marked with a '1' in the upper right corner of the lifeline box. It implies that the Singleton pattern is used to gain visibility to the objectthe meaning of that won't be clear at this time, but will be upon reading its description on p. 442. See Figure 15.6.

                                                                                                                                                                                                                                                                                                                                                                                                  图 15.6.交互图中的单例。





                                                                                                                                                                                                                                                                                                                                                                                                    15.4. 基本序列图表示法

                                                                                                                                                                                                                                                                                                                                                                                                    15.4. Basic Sequence Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                    生命线箱和生命线

                                                                                                                                                                                                                                                                                                                                                                                                    Lifeline Boxes and Lifelines

                                                                                                                                                                                                                                                                                                                                                                                                    与通信图相反,在序列图中,生命线框包括一条延伸到它们下方的垂直线这些是实际的生命线。尽管几乎所有的 UML 示例都显示生命线为虚线(由于 UML 1 的影响),但实际上 UML 2 规范说它可能是实线虚线。

                                                                                                                                                                                                                                                                                                                                                                                                    In contrast to communication diagrams, in sequence diagrams the lifeline boxes include a vertical line extending below themthese are the actual lifelines. Although virtually all UML examples show the lifeline as dashed (because of UML 1 influence), in fact the UML 2 specification says it may be solid or dashed.



                                                                                                                                                                                                                                                                                                                                                                                                    消息

                                                                                                                                                                                                                                                                                                                                                                                                    Messages

                                                                                                                                                                                                                                                                                                                                                                                                    对象之间的每个(典型的同步)消息都用一个消息表达式表示,该表达式位于垂直生命线之间的实心箭头[3]上(参见图 15.7)。时间排序是从生命线的上到下组织的。

                                                                                                                                                                                                                                                                                                                                                                                                    Each (typical synchronous) message between objects is represented with a message expression on a filled-arrowed[3] solid line between the vertical lifelines (see Figure 15.7). The time ordering is organized from top to bottom of lifelines.

                                                                                                                                                                                                                                                                                                                                                                                                    [3] 打开的消息箭头表示交互图中的异步消息。

                                                                                                                                                                                                                                                                                                                                                                                                    [3] An open message arrow means an asynchronous message in an interaction diagram.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.7.带有执行规范栏的消息和控制焦点。



                                                                                                                                                                                                                                                                                                                                                                                                    图 15.7 的例子中,起始消息在 UML 中称为找到的消息,以一个打开的实心球表示;这意味着不会指定发件人、未知或消息来自随机来源。但是,按照惯例,团队或工具可能会忽略显示此消息,而是使用不带球的常规消息行,按照惯例,它是一条找到的消息。[4]

                                                                                                                                                                                                                                                                                                                                                                                                    In the example of Figure 15.7 the starting message is called a found message in the UML, shown with an opening solid ball; it implies the sender will not be specified, is not known, or that the message is coming from a random source. However, by convention a team or tool may ignore showing this, and instead use a regular message line without the ball, intending by convention it is a found message.[4]

                                                                                                                                                                                                                                                                                                                                                                                                    [4] 因此,许多书籍示例不会纠结 found message 表示法。

                                                                                                                                                                                                                                                                                                                                                                                                    [4] Therefore, many of the book examples won't bother with the found message notation.

                                                                                                                                                                                                                                                                                                                                                                                                    Control 和 Execution Specification Bars 的焦点

                                                                                                                                                                                                                                                                                                                                                                                                    Focus of Control and Execution Specification Bars

                                                                                                                                                                                                                                                                                                                                                                                                    如图 15.7 所示,序列图还可以使用执行规范栏(以前称为激活栏或在 UML 1 中简称为激活)来显示控制的焦点(非正式地,在常规的阻塞调用中,操作在调用堆栈上)。该条形图是可选的。

                                                                                                                                                                                                                                                                                                                                                                                                    As illustrated in Figure 15.7, sequence diagrams may also show the focus of control (informally, in a regular blocking call, the operation is on the call stack) using an execution specification bar (previously called an activation bar or simply an activation in UML 1). The bar is optional.

                                                                                                                                                                                                                                                                                                                                                                                                    指南: 使用 UML CASE 工具时,绘制条形图更常见(通常是自动的),而在绘制壁画时则不太常见。

                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: Drawing the bar is more common (and often automatic) when using a UML CASE tool, and less common when wall sketching.

                                                                                                                                                                                                                                                                                                                                                                                                    说明 Reply 或 Return

                                                                                                                                                                                                                                                                                                                                                                                                    Illustrating Reply or Returns

                                                                                                                                                                                                                                                                                                                                                                                                    有两种方法可以显示消息的返回结果:

                                                                                                                                                                                                                                                                                                                                                                                                    There are two ways to show the return result from a message:

                                                                                                                                                                                                                                                                                                                                                                                                    1. 使用消息语法 returnVar = message(parameter)。

                                                                                                                                                                                                                                                                                                                                                                                                    2. Using the message syntax returnVar = message(parameter).

                                                                                                                                                                                                                                                                                                                                                                                                    3. 在激活栏的末尾使用回复 (或返回) 消息行。

                                                                                                                                                                                                                                                                                                                                                                                                    4. Using a reply (or return) message line at the end of an activation bar.

                                                                                                                                                                                                                                                                                                                                                                                                    这两者在实践中都很常见。在绘制草图时,我更喜欢第一种方法,因为它更省力。如果使用 reply 行,则该行通常标有返回值的任意描述。参见图 15.8

                                                                                                                                                                                                                                                                                                                                                                                                    Both are common in practice. I prefer the first approach when sketching, as it's less effort. If the reply line is used, the line is normally labelled with an arbitrary description of the returning value. See Figure 15.8.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.8.显示消息返回结果的两种方法。



                                                                                                                                                                                                                                                                                                                                                                                                    向 “self” 或 “this” 发送消息

                                                                                                                                                                                                                                                                                                                                                                                                    Messages to "self" or "this"

                                                                                                                                                                                                                                                                                                                                                                                                    您可以使用嵌套的激活栏来显示从对象发送到自身的消息(参见图 15.9)。

                                                                                                                                                                                                                                                                                                                                                                                                    You can show a message being sent from an object to itself by using a nested activation bar (see Figure 15.9).

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.9.向 “this” 发送消息。



                                                                                                                                                                                                                                                                                                                                                                                                    实例创建

                                                                                                                                                                                                                                                                                                                                                                                                    Creation of Instances

                                                                                                                                                                                                                                                                                                                                                                                                    对象创建表示法如图 15.10 所示。请注意 UML 规定的线。[5] 如果是常规同步消息(例如暗示调用 Java 构造函数),则箭头填充,如果是异步调用,则打开(棒箭头)。消息名称 create 不是必需的,任何内容都是合法的,但它是 UML 惯用语。

                                                                                                                                                                                                                                                                                                                                                                                                    Object creation notation is shown in Figure 15.10. Note the UML-mandated dashed line.[5] The arrow is filled if it's a regular synchronous message (such as implying invoking a Java constructor), or open (stick arrow) if an asynchronous call. The message name create is not requiredanything is legalbut it's a UML idiom.

                                                                                                                                                                                                                                                                                                                                                                                                    [5] 我认为要求虚线没有任何价值,但它在规范中......许多作者示例使用实线,规范的早期草案版本也是如此。

                                                                                                                                                                                                                                                                                                                                                                                                    [5] I see no value in requiring a dashed line, but it's in the spec… Many author examples use a solid line, as early draft versions of the spec did as well.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.10.实例创建和对象生命线。



                                                                                                                                                                                                                                                                                                                                                                                                    在带有实心箭头的虚线上的创建消息的典型解释(在 Java 或 C# 等语言中)是 “invoke the new operator and call the constructor”。

                                                                                                                                                                                                                                                                                                                                                                                                    The typical interpretation (in languages such as Java or C#) of a create message on a dashed line with a filled arrow is "invoke the new operator and call the constructor".

                                                                                                                                                                                                                                                                                                                                                                                                    对象生命线和对象销毁

                                                                                                                                                                                                                                                                                                                                                                                                    Object Lifelines and Object Destruction

                                                                                                                                                                                                                                                                                                                                                                                                    在某些情况下,需要显示对象的显式销毁。例如,当使用没有自动垃圾回收的 C++ 时,或者当您想要特别指示某个对象不再可用时(例如关闭的数据库连接)。UML 生命线表示法提供了一种表示这种销毁的方法(参见图 15.11)。

                                                                                                                                                                                                                                                                                                                                                                                                    In some circumstances it is desirable to show explicit destruction of an object. For example, when using C++ which does not have automatic garbage collection, or when you want to especially indicate an object is no longer usable (such as a closed database connection). The UML lifeline notation provides a way to express this destruction (see Figure 15.11).

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.11.对象销毁。



                                                                                                                                                                                                                                                                                                                                                                                                    UML 序列图中的图帧

                                                                                                                                                                                                                                                                                                                                                                                                    Diagram Frames in UML Sequence Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                    为了支持条件和循环结构(以及许多其他内容),UML 使用[6] 框架是图表的区域或片段;它们有一个运算符或标签(例如 loop)和一个 guard[7](条件子句)。参见图 15.12

                                                                                                                                                                                                                                                                                                                                                                                                    To support conditional and looping constructs (among many other things), the UML uses frames.[6] Frames are regions or fragments of the diagrams; they have an operator or label (such as loop) and a guard[7] (conditional clause). See Figure 15.12.

                                                                                                                                                                                                                                                                                                                                                                                                    [6] 也称为图表框架或交互框架。

                                                                                                                                                                                                                                                                                                                                                                                                    [6] Also called diagram frames or interaction frames.

                                                                                                                                                                                                                                                                                                                                                                                                    [7] [boolean test] 守卫应该放在它所属的生命线上。

                                                                                                                                                                                                                                                                                                                                                                                                    [7] The [boolean test] guard should be placed over the lifeline to which it belongs.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.12.示例 UML 帧。



                                                                                                                                                                                                                                                                                                                                                                                                    下表总结了一些常见的帧运算符:

                                                                                                                                                                                                                                                                                                                                                                                                    The following table summarizes some common frame operators:

                                                                                                                                                                                                                                                                                                                                                                                                    Frame Operator

                                                                                                                                                                                                                                                                                                                                                                                                    Frame Operator

                                                                                                                                                                                                                                                                                                                                                                                                    意义

                                                                                                                                                                                                                                                                                                                                                                                                    Meaning

                                                                                                                                                                                                                                                                                                                                                                                                    alt

                                                                                                                                                                                                                                                                                                                                                                                                    alt

                                                                                                                                                                                                                                                                                                                                                                                                    守卫中表示的互斥条件逻辑的替代片段。

                                                                                                                                                                                                                                                                                                                                                                                                    Alternative fragment for mutual exclusion conditional logic expressed in the guards.

                                                                                                                                                                                                                                                                                                                                                                                                    loop

                                                                                                                                                                                                                                                                                                                                                                                                    当 guard 为 true 时循环片段。也可以写 loop(n) 来表示循环 n 次。有讨论说,规范将得到增强以定义 FOR 循环,例如 loop(i, 1, 10)

                                                                                                                                                                                                                                                                                                                                                                                                    Loop fragment while guard is true. Can also write loop(n) to indicate looping n times. There is discussion that the specification will be enhanced to define a FOR loop, such as loop(i, 1, 10)

                                                                                                                                                                                                                                                                                                                                                                                                    选择

                                                                                                                                                                                                                                                                                                                                                                                                    opt

                                                                                                                                                                                                                                                                                                                                                                                                    在 guard 为 true 时执行的可选 fragment。

                                                                                                                                                                                                                                                                                                                                                                                                    Optional fragment that executes if guard is true.

                                                                                                                                                                                                                                                                                                                                                                                                    par

                                                                                                                                                                                                                                                                                                                                                                                                    并行执行的并行片段。

                                                                                                                                                                                                                                                                                                                                                                                                    Parallel fragments that execute in parallel.

                                                                                                                                                                                                                                                                                                                                                                                                    地区

                                                                                                                                                                                                                                                                                                                                                                                                    region

                                                                                                                                                                                                                                                                                                                                                                                                    只有一个线程可以运行的关键区域。

                                                                                                                                                                                                                                                                                                                                                                                                    Critical region within which only one thread can run.



                                                                                                                                                                                                                                                                                                                                                                                                    循环

                                                                                                                                                                                                                                                                                                                                                                                                    Looping

                                                                                                                                                                                                                                                                                                                                                                                                    显示循环的 LOOP 帧表示法如图 15.12 所示。

                                                                                                                                                                                                                                                                                                                                                                                                    The LOOP frame notation to show looping is shown in Figure 15.12.

                                                                                                                                                                                                                                                                                                                                                                                                    条件消息

                                                                                                                                                                                                                                                                                                                                                                                                    Conditional Messages

                                                                                                                                                                                                                                                                                                                                                                                                    OPT 帧放置在一条或多条消息周围。请注意,守卫位于相关的生命线上。参见图 15.13

                                                                                                                                                                                                                                                                                                                                                                                                    An OPT frame is placed around one or more messages. Notice that the guard is placed over the related lifeline. See Figure 15.13.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.13.条件消息。



                                                                                                                                                                                                                                                                                                                                                                                                    UML 1.x 样式中的条件消息仍然有用?

                                                                                                                                                                                                                                                                                                                                                                                                    Conditional Messages in UML 1.x StyleStill Useful?

                                                                                                                                                                                                                                                                                                                                                                                                    显示单个条件消息的 UML 2.x 表示法是重量级的,需要围绕一条消息的整个 OPT 帧框(参见图 15.13)。序列图中单个条件消息的旧 UML 1.x 表示法在 UML 2 中并不合法,但非常简单,尤其是在绘制草图时,它可能会在未来几年内流行起来。参见图 15.14

                                                                                                                                                                                                                                                                                                                                                                                                    The UML 2.x notation to show a single conditional message is heavyweight, requiring an entire OPT frame box around one message (see Figure 15.13). The older UML 1.x notation for single conditional messages in sequence diagrams is not legal in UML 2, but so simple that especially when sketching it will probably be popular for years to come. See Figure 15.14.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.14.采用 UML 1.x 表示法的条件消息一种简单的样式。



                                                                                                                                                                                                                                                                                                                                                                                                    指南: 在绘制草图时,仅对简单的单条消息使用 UML 1 样式。

                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: Use UML 1 style only for simple single messages when sketching.

                                                                                                                                                                                                                                                                                                                                                                                                    互斥条件消息

                                                                                                                                                                                                                                                                                                                                                                                                    Mutually Exclusive Conditional Messages

                                                                                                                                                                                                                                                                                                                                                                                                    ALT 框架放置在互斥的分项选择周围。参见图 15.15

                                                                                                                                                                                                                                                                                                                                                                                                    An ALT frame is placed around the mutually exclusive alternatives. See Figure 15.15.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.15.互斥的条件消息。



                                                                                                                                                                                                                                                                                                                                                                                                    对集合进行迭代

                                                                                                                                                                                                                                                                                                                                                                                                    Iteration Over a Collection

                                                                                                                                                                                                                                                                                                                                                                                                    一种常见的算法是迭代集合的所有成员(例如列表或映射),并向每个成员发送相同的消息。通常,最终会使用某种迭代器对象,例如 java.util.Iterator 的实现或 C++ 标准库迭代器,尽管在序列图中,为了简洁或抽象,不需要显示该低级“机制”。

                                                                                                                                                                                                                                                                                                                                                                                                    A common algorithm is to iterate over all members of a collection (such as a list or map), sending the same message to each. Often, some kind of iterator object is ultimately used, such as an implementation of java.util.Iterator or a C++ standard library iterator, although in the sequence diagram that low-level "mechanism" need not be shown in the interest of brevity or abstraction.

                                                                                                                                                                                                                                                                                                                                                                                                    在撰写本文时,UML 规范还没有(并且可能永远不会)针对这种情况的官方惯用语。图 15.16图 15.17 中显示了两种选择,UML 2 交互规范的领导者进行了回顾。

                                                                                                                                                                                                                                                                                                                                                                                                    At the time of this writing, the UML specification did not (and may never) have an official idiom for this case. Two alternatives are shownreviewed with the leader of the UML 2 interaction specificationin Figure 15.16 and Figure 15.17.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.16.使用相对显式的表示法对集合进行迭代。



                                                                                                                                                                                                                                                                                                                                                                                                    图 15.17.对集合进行迭代,使事情更加隐含。



                                                                                                                                                                                                                                                                                                                                                                                                    请注意图 15.16 生命线中的 selector 表达式 lineItems[i]。选择器表达式用于从组中选择一个对象。Lifeline 参与者应代表一个对象,而不是一个集合。

                                                                                                                                                                                                                                                                                                                                                                                                    Note the selector expression lineItems[i] in the lifeline of Figure 15.16. The selector expression is used to select one object from a group. Lifeline participants should represent one object, not a collection.

                                                                                                                                                                                                                                                                                                                                                                                                    例如,在 Java 中,下面的代码清单是一种可能的实现,它使用其增强的 for 语句(C# 具有相同的语句)将图 15.16 中递增变量 i 的显式使用映射到 Java 中的惯用解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                    In Java, for example, the following code listing is a possible implementation that maps the explicit use of the incrementing variable i in Figure 15.16 to an idiomatic solution in Java, using its enhanced for statement (C# has the same).

                                                                                                                                                                                                                                                                                                                                                                                                    public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                new ArrayList<SalesLineItem>();
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public Money getTotal()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       Money total = new Money();
                                                                                                                                                                                                                                                                                                                                                                                                       Money subtotal = null;
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                       for ( SalesLineItem lineItem : lineItems )
                                                                                                                                                                                                                                                                                                                                                                                                       {
                                                                                                                                                                                                                                                                                                                                                                                                          subtotal = lineItem.getSubtotal();
                                                                                                                                                                                                                                                                                                                                                                                                          total.add( subtotal );
                                                                                                                                                                                                                                                                                                                                                                                                       }
                                                                                                                                                                                                                                                                                                                                                                                                       return total;
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                new ArrayList<SalesLineItem>();
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public Money getTotal()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       Money total = new Money();
                                                                                                                                                                                                                                                                                                                                                                                                       Money subtotal = null;
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                       for ( SalesLineItem lineItem : lineItems )
                                                                                                                                                                                                                                                                                                                                                                                                       {
                                                                                                                                                                                                                                                                                                                                                                                                          subtotal = lineItem.getSubtotal();
                                                                                                                                                                                                                                                                                                                                                                                                          total.add( subtotal );
                                                                                                                                                                                                                                                                                                                                                                                                       }
                                                                                                                                                                                                                                                                                                                                                                                                       return total;
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                                                                                    另一种变化如图 15.17 所示;意图相同,但不包括细节。团队或工具可以通过约定就这种简单的样式达成一致,以暗示对所有集合元素进行迭代。[8]

                                                                                                                                                                                                                                                                                                                                                                                                    Another variation is shown in Figure 15.17; the intent is the same, but details are excluded. A team or tool could agree on this simple style by convention to imply iteration over all the collection elements.[8]

                                                                                                                                                                                                                                                                                                                                                                                                    [8] 我在本书的后面使用了这种风格。

                                                                                                                                                                                                                                                                                                                                                                                                    [8] I use this style later in the book.

                                                                                                                                                                                                                                                                                                                                                                                                    框架嵌套

                                                                                                                                                                                                                                                                                                                                                                                                    Nesting of Frames

                                                                                                                                                                                                                                                                                                                                                                                                    框架可以嵌套。参见图 15.18

                                                                                                                                                                                                                                                                                                                                                                                                    Frames can be nested. See Figure 15.18.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.18.框架嵌套。



                                                                                                                                                                                                                                                                                                                                                                                                    如何关联交互图?

                                                                                                                                                                                                                                                                                                                                                                                                    How to Relate Interaction Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.19 可能比文字更能说明问题。交互事件(也称为交互使用)是对另一个交互中的交互的引用。例如,当您想要简化一个图表并将一个部分分解为另一个图表时,或者存在可重用的交互事件时,它非常有用。UML 工具利用了它们,因为它们在关联和链接图表方面很有用。

                                                                                                                                                                                                                                                                                                                                                                                                    Figure 15.19 illustrates probably better than words. An interaction occurrence (also called an interaction use) is a reference to an interaction within another interaction. It is useful, for example, when you want to simplify a diagram and factor out a portion into another diagram, or there is a reusable interaction occurrence. UML tools take advantage of them, because of their usefulness in relating and linking diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.19.交互发生示例、sdref 帧。



                                                                                                                                                                                                                                                                                                                                                                                                    它们由两个相关框架创建:

                                                                                                                                                                                                                                                                                                                                                                                                    They are created with two related frames:

                                                                                                                                                                                                                                                                                                                                                                                                    • 围绕整个序列图的帧[9],标有标签 sd 和名称,例如 AuthenticateUser

                                                                                                                                                                                                                                                                                                                                                                                                      [9] 交互发生和参考帧也可用于通信图。

                                                                                                                                                                                                                                                                                                                                                                                                    • a frame around an entire sequence diagram[9] , labeled with the tag sd and a name, such as AuthenticateUser

                                                                                                                                                                                                                                                                                                                                                                                                      [9] Interaction occurrences and ref frames can also be used for communication diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                    • 标记为 ref 的帧,称为 reference,它引用另一个命名的序列图;它是实际的交互事件

                                                                                                                                                                                                                                                                                                                                                                                                    • a frame tagged ref, called a reference, that refers to another named sequence diagram; it is the actual interaction occurrence

                                                                                                                                                                                                                                                                                                                                                                                                    交互概览图还包含一组参考框架 (交互发生次数)。这些图将引用组织成一个更大的逻辑和流程结构。

                                                                                                                                                                                                                                                                                                                                                                                                    Interaction overview diagrams also contain a set of reference frames (interaction occurrences). These diagrams organized references into a larger structure of logic and process flow.

                                                                                                                                                                                                                                                                                                                                                                                                    指南: 命名,任何序列图都可以用 sd 帧包围。frame 并命名一个,当你想使用 ref frame 来引用它时。

                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: Any sequence diagram can be surrounded with an sd frame, to name it. Frame and name one when you want to refer to it using a ref frame.

                                                                                                                                                                                                                                                                                                                                                                                                    向类发送消息以调用静态(或类)方法

                                                                                                                                                                                                                                                                                                                                                                                                    Messages to Classes to Invoke Static (or Class) Methods

                                                                                                                                                                                                                                                                                                                                                                                                    你可以使用生命线框标签来显示类或静态方法调用,该标签指示接收对象是一个类,或者更准确地说,是一个元类实例(参见图 15.20)。

                                                                                                                                                                                                                                                                                                                                                                                                    You can show class or static method calls by using a lifeline box label that indicates the receiving object is a class, or more precisely, an instance of a metaclass (see Figure 15.20).

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.20.调用类或静态方法;将类对象显示为元类的实例。



                                                                                                                                                                                                                                                                                                                                                                                                    我是什么意思?例如,在 Java 和 Smalltalk 中,所有类在概念上或字面上都是类 Class实例;在 .NET 类中是类 Type 的实例。类 ClassType元类,这意味着它们的实例本身就是类。特定类(如类 Calendar)本身是类 Class 的实例。因此,类 Calendar 是元类的实例!在尝试理解这一点之前喝点啤酒可能会有所帮助。

                                                                                                                                                                                                                                                                                                                                                                                                    What do I mean? For example, in Java and Smalltalk, all classes are conceptually or literally instances of class Class; in .NET classes are instances of class Type. The classes Class and Type are metaclasses, which means their instances are themselves classes. A specific class, such as class Calendar, is itself an instance of class Class. Thus, class Calendar is an instance of a metaclass! It may help to drink some beer before trying to understand this.

                                                                                                                                                                                                                                                                                                                                                                                                    在代码中,可能的实现是:

                                                                                                                                                                                                                                                                                                                                                                                                    In code, a likely implementation is:

                                                                                                                                                                                                                                                                                                                                                                                                    public class Foo
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       // static method call on class Calendar
                                                                                                                                                                                                                                                                                                                                                                                                       Locale[] locales = Calendar.getAvailableLocales();
                                                                                                                                                                                                                                                                                                                                                                                                       // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public class Foo
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       // static method call on class Calendar
                                                                                                                                                                                                                                                                                                                                                                                                       Locale[] locales = Calendar.getAvailableLocales();
                                                                                                                                                                                                                                                                                                                                                                                                       // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                                                                                    多态消息和案例

                                                                                                                                                                                                                                                                                                                                                                                                    Polymorphic Messages and Cases

                                                                                                                                                                                                                                                                                                                                                                                                    多态性是 OO 设计的基础。如何在序列图中显示它?这是一个常见的 UML 问题。一种方法是使用多个序列图,一个向抽象超类或接口对象显示多态消息,然后单独列出详细说明每个多态情况的序列图,每个序列图以找到的多态消息开头。图 15.21 说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                    Polymorphism is fundamental to OO design. How to show it in a sequence diagram? That's a common UML question. One approach is to use multiple sequence diagramsone that shows the polymorphic message to the abstract superclass or interface object, and then separate sequence diagrams detailing each polymorphic case, each starting with a found polymorphic message. Figure 15.21 illustrates.

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.21.一种在序列图中对多态情况进行建模的方法。



                                                                                                                                                                                                                                                                                                                                                                                                    异步和同步调用

                                                                                                                                                                                                                                                                                                                                                                                                    Asynchronous and Synchronous Calls

                                                                                                                                                                                                                                                                                                                                                                                                    异步消息调用不会等待响应;它不会阻塞。它们用于多线程环境,例如 .NET 和 Java,以便可以创建和启动新的执行线程。例如,在 Java 中,您可以将 Thread.startRunnable.run(由 Thread.start 调用)消息视为在新线程上启动执行的异步起点。

                                                                                                                                                                                                                                                                                                                                                                                                    An asynchronous message call does not wait for a response; it doesn't block. They are used in multi-threaded environments such as .NET and Java so that new threads of execution can be created and initiated. In Java, for example, you may think of the Thread.start or Runnable.run (called by Thread.start) message as the asynchronous starting point to initiate execution on a new thread.

                                                                                                                                                                                                                                                                                                                                                                                                    异步调用的 UML 表示法是棒状箭头消息;常规的同步(阻塞)调用用实心箭头显示(参见图 15.22)。

                                                                                                                                                                                                                                                                                                                                                                                                    The UML notation for asynchronous calls is a stick arrow message; regular synchronous (blocking) calls are shown with a filled arrow (see Figure 15.22).

                                                                                                                                                                                                                                                                                                                                                                                                    图 15.22.异步调用和活动对象。



                                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                                    这个箭头的差异很微妙。当绘制 UML 墙时,通常使用棒状箭头来表示同步调用,因为它更容易绘制。因此,在阅读 UML 交互图时,不要假设箭头的形状是正确的!

                                                                                                                                                                                                                                                                                                                                                                                                    This arrow difference is subtle. And when wall sketching UML, it is common to use a stick arrow to mean a synchronous call because it's easier to draw. Therefore, when reading a UML interaction diagram don't assume the shape of the arrow is correct!



                                                                                                                                                                                                                                                                                                                                                                                                    图 15.22 中的 Clock 等对象也称为活动对象,每个实例运行并控制自己的执行线程。在 UML 中,它可能在生命线框的左侧和右侧以双垂直线显示。相同的表示法用于其实例是活动对象的活动类

                                                                                                                                                                                                                                                                                                                                                                                                    An object such as the Clock in Figure 15.22 is also known as an active objecteach instance runs on and controls its own thread of execution. In the UML, it may be shown with double vertical lines on the left and right sides of the lifeline box. The same notation is used for an active class whose instances are active objects.



                                                                                                                                                                                                                                                                                                                                                                                                    在 Java 中,图 15.22 的可能实现如下。请注意,代码中的 Thread 对象被排除在 UML 图之外,因为它只是在 Java 中实现异步调用的一致 “开销” 机制。

                                                                                                                                                                                                                                                                                                                                                                                                    In Java, a likely implementation for Figure 15.22 follows. Notice that the Thread object in the code is excluded from the UML diagram, because it is simply a consistent "overhead" mechanism to realize an asynchronous call in Java.

                                                                                                                                                                                                                                                                                                                                                                                                    public class ClockStarter
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void startClock()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       Thread t = new Thread( new Clock() );
                                                                                                                                                                                                                                                                                                                                                                                                       t.start(); // asynchronous call to the 'run' method on the Clock
                                                                                                                                                                                                                                                                                                                                                                                                       System.runFinalization(); // example follow-on message
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // objects should implement the Runnable interface
                                                                                                                                                                                                                                                                                                                                                                                                    // in Java to be used on new threads
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public class Clock implements Runnable
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void run()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       while ( true ) // loop forever on own thread
                                                                                                                                                                                                                                                                                                                                                                                                       {
                                                                                                                                                                                                                                                                                                                                                                                                          // …
                                                                                                                                                                                                                                                                                                                                                                                                       }
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public class ClockStarter
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void startClock()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       Thread t = new Thread( new Clock() );
                                                                                                                                                                                                                                                                                                                                                                                                       t.start(); // asynchronous call to the 'run' method on the Clock
                                                                                                                                                                                                                                                                                                                                                                                                       System.runFinalization(); // example follow-on message
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // objects should implement the Runnable interface
                                                                                                                                                                                                                                                                                                                                                                                                    // in Java to be used on new threads
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                    public class Clock implements Runnable
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                    public void run()
                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                       while ( true ) // loop forever on own thread
                                                                                                                                                                                                                                                                                                                                                                                                       {
                                                                                                                                                                                                                                                                                                                                                                                                          // …
                                                                                                                                                                                                                                                                                                                                                                                                       }
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                                                                                      15.5. 基本通信图表示法

                                                                                                                                                                                                                                                                                                                                                                                                      15.5. Basic Communication Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                      链接

                                                                                                                                                                                                                                                                                                                                                                                                      Links

                                                                                                                                                                                                                                                                                                                                                                                                      链接是两个对象之间的连接路径;它表示对象之间可以进行某种形式的导航和可见性(参见图 15.23)。更正式地说,链接是关联的实例。例如,有一个从 RegisterSale 的 navigationor 路径,消息可能沿着该路径流动,例如 makePayment 消息。

                                                                                                                                                                                                                                                                                                                                                                                                      A link is a connection path between two objects; it indicates some form of navigation and visibility between the objects is possible (see Figure 15.23). More formally, a link is an instance of an association. For example, there is a linkor path of navigationfrom a Register to a Sale, along which messages may flow, such as the makePayment message.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.23.链接线。



                                                                                                                                                                                                                                                                                                                                                                                                      注意

                                                                                                                                                                                                                                                                                                                                                                                                      Note

                                                                                                                                                                                                                                                                                                                                                                                                      请注意,多条消息和双向消息都沿着同一个链接流动。每条消息没有一个链接行;所有消息都在同一条线路上流动,这就像一条允许双向消息流量的道路。

                                                                                                                                                                                                                                                                                                                                                                                                      Note that multiple messages, and messages both ways, flow along the same single link. There isn't one link line per message; all messages flow on the same line, which is like a road allowing two-way message traffic.



                                                                                                                                                                                                                                                                                                                                                                                                      消息

                                                                                                                                                                                                                                                                                                                                                                                                      Messages

                                                                                                                                                                                                                                                                                                                                                                                                      对象之间的每条消息都用消息表达式和指示消息方向的小箭头表示。许多消息可能沿着这个链接流动(图 15.24)。添加序列号以显示当前控制线程中消息的 Sequences。

                                                                                                                                                                                                                                                                                                                                                                                                      Each message between objects is represented with a message expression and small arrow indicating the direction of the message. Many messages may flow along this link (Figure 15.24). A sequence number is added to show the sequential order of messages in the current thread of control.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.24.消息。



                                                                                                                                                                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                                                                                                                                                                      不要对开始消息进行编号。这样做是合法的,但如果不这样做,则会简化总体编号。

                                                                                                                                                                                                                                                                                                                                                                                                      Don't number the starting message. It's legal to do so, but simplifies the overall numbering if you don't.



                                                                                                                                                                                                                                                                                                                                                                                                      向 “self” 或 “this” 发送消息

                                                                                                                                                                                                                                                                                                                                                                                                      Messages to "self" or "this"

                                                                                                                                                                                                                                                                                                                                                                                                      消息可以从对象发送到自身(图 15.25)。这可以通过指向自身的链接来说明,消息沿着链接流动。

                                                                                                                                                                                                                                                                                                                                                                                                      A message can be sent from an object to itself (Figure 15.25). This is illustrated by a link to itself, with messages flowing along the link.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.25.向 “this” 发送消息。



                                                                                                                                                                                                                                                                                                                                                                                                      实例创建

                                                                                                                                                                                                                                                                                                                                                                                                      Creation of Instances

                                                                                                                                                                                                                                                                                                                                                                                                      任何消息都可用于创建实例,但 UML 中的约定是使用名为 create 的消息来实现此目的(有些使用 new)。参见图 15.26。如果使用另一个(不太明显的)消息名称,则该消息可能会使用 UML 构造型进行注释,例如:“创建”。create 消息可能包含参数,指示初始值的传递。例如,这表示 Java 中带有参数的构造函数调用。此外,可以选择将 UML 标记值 {new} 添加到生命线框中以突出显示创建。标记值是 UML 中的一种灵活的扩展机制,用于向 UML 元素添加具有语义意义的信息。

                                                                                                                                                                                                                                                                                                                                                                                                      Any message can be used to create an instance, but the convention in the UML is to use a message named create for this purpose (some use new). See Figure 15.26. If another (less obvious) message name is used, the message may be annotated with a UML stereotype, like so: «create». The create message may include parameters, indicating the passing of initial values. This indicates, for example, a constructor call with parameters in Java. Furthermore, the UML tagged value {new} may optionally be added to the lifeline box to highlight the creation. Tagged values are a flexible extension mechanism in the UML to add semantically meaningful information to a UML element.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.26.实例创建。



                                                                                                                                                                                                                                                                                                                                                                                                      消息编号排序

                                                                                                                                                                                                                                                                                                                                                                                                      Message Number Sequencing

                                                                                                                                                                                                                                                                                                                                                                                                      消息的顺序用序列号表示,如图 15.27 所示。编号方案为:

                                                                                                                                                                                                                                                                                                                                                                                                      The order of messages is illustrated with sequence numbers, as shown in Figure 15.27. The numbering scheme is:

                                                                                                                                                                                                                                                                                                                                                                                                      1. 第一条消息没有编号。因此,msg1 未编号。[10]

                                                                                                                                                                                                                                                                                                                                                                                                        [10]实际上,起始编号是合法的,但它使所有后续编号更加尴尬,从而产生另一个级别的编号嵌套,而不是其他必要的。

                                                                                                                                                                                                                                                                                                                                                                                                      2. The first message is not numbered. Thus, msg1 is unnumbered.[10]

                                                                                                                                                                                                                                                                                                                                                                                                        [10] Actually, a starting number is legal, but it makes all subsequent numbering more awkward, creating another level of number-nesting deeper than otherwise necessary.

                                                                                                                                                                                                                                                                                                                                                                                                      3. 后续消息的顺序和嵌套以合法编号方案显示,其中嵌套消息附加了一个编号。通过将传入消息编号追加到传出消息编号来表示嵌套。

                                                                                                                                                                                                                                                                                                                                                                                                      4. The order and nesting of subsequent messages is shown with a legal numbering scheme in which nested messages have a number appended to them. You denote nesting by prepending the incoming message number to the outgoing message number.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.27.序列号。



                                                                                                                                                                                                                                                                                                                                                                                                      图 15.28 显示了一个更复杂的情况。

                                                                                                                                                                                                                                                                                                                                                                                                      Figure 15.28 shows a more complex case.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.28.复杂的序列号。



                                                                                                                                                                                                                                                                                                                                                                                                      条件消息

                                                                                                                                                                                                                                                                                                                                                                                                      Conditional Messages

                                                                                                                                                                                                                                                                                                                                                                                                      您可以通过在序号后面加上方括号中的条件子句来显示条件消息(图 15.29),类似于迭代子句。仅当子句的计算结果为 true 时,才会发送消息。

                                                                                                                                                                                                                                                                                                                                                                                                      You show a conditional message (Figure 15.29) by following a sequence number with a conditional clause in square brackets, similar to an iteration clause. The message is only sent if the clause evaluates to true.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.29.条件消息。



                                                                                                                                                                                                                                                                                                                                                                                                      互斥条件路径

                                                                                                                                                                                                                                                                                                                                                                                                      Mutually Exclusive Conditional Paths

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.30 中的示例说明了具有互斥条件 paths 的序列号。

                                                                                                                                                                                                                                                                                                                                                                                                      The example in Figure 15.30 illustrates the sequence numbers with mutually exclusive conditional paths.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.30.互斥消息。



                                                                                                                                                                                                                                                                                                                                                                                                      在这种情况下,我们必须使用条件路径字母修改序列表达式。按照惯例,使用的第一个字母是 a图 15.30 指出 1a1b 可以在 msg1 之后执行。两者都是序列号 1,因为两者都可能是第一条消息。

                                                                                                                                                                                                                                                                                                                                                                                                      In this case we must modify the sequence expressions with a conditional path letter. The first letter used is a by convention. Figure 15.30 states that either 1a or 1b could execute after msg1. Both are sequence number 1 since either could be the first internal message.

                                                                                                                                                                                                                                                                                                                                                                                                      请注意,后续嵌套消息仍然始终在其外部消息序列前面。因此 1b.11b 中的嵌套消息。

                                                                                                                                                                                                                                                                                                                                                                                                      Note that subsequent nested messages are still consistently prepended with their outer message sequence. Thus 1b.1 is nested message within 1b.

                                                                                                                                                                                                                                                                                                                                                                                                      迭代或循环

                                                                                                                                                                                                                                                                                                                                                                                                      Iteration or Looping

                                                                                                                                                                                                                                                                                                                                                                                                      迭代表示法如图 15.31 所示。如果 iteration 子句的细节对建模者来说不重要,则可以使用简单的 *。

                                                                                                                                                                                                                                                                                                                                                                                                      Iteration notation is shown in Figure 15.31. If the details of the iteration clause are not important to the modeler, a simple * can be used.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.31.迭 代。



                                                                                                                                                                                                                                                                                                                                                                                                      对集合进行迭代

                                                                                                                                                                                                                                                                                                                                                                                                      Iteration Over a Collection

                                                                                                                                                                                                                                                                                                                                                                                                      一种常见的算法是迭代集合的所有成员(例如列表或映射),并向每个成员发送相同的消息。在通信图中,这可以总结为图 15.32 所示,尽管没有正式的 UML 约定。

                                                                                                                                                                                                                                                                                                                                                                                                      A common algorithm is to iterate over all members of a collection (such as a list or map), sending the same message to each. In communication diagrams, this could be summarized as shown in Figure 15.32, although there is no official UML convention.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.32.对集合进行迭代。



                                                                                                                                                                                                                                                                                                                                                                                                      向类发送消息以调用静态 (类) 方法

                                                                                                                                                                                                                                                                                                                                                                                                      Messages to a Classes to Invoke Static (Class) Methods

                                                                                                                                                                                                                                                                                                                                                                                                      请参阅第 236 页序列图案例中对元类的讨论,以理解图 15.33 中示例的目的。

                                                                                                                                                                                                                                                                                                                                                                                                      See the discussion of metaclasses in the sequence diagram case on p. 236, to understand the purpose of the example in Figure 15.33.

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.33.向类对象发送消息(静态方法调用)。



                                                                                                                                                                                                                                                                                                                                                                                                      多态消息和案例

                                                                                                                                                                                                                                                                                                                                                                                                      Polymorphic Messages and Cases

                                                                                                                                                                                                                                                                                                                                                                                                      有关相关的上下文、类层次结构和序列图示例,请参阅图 15.21。与序列图的情况一样,可以使用多个通信图来显示每个具体的多态情况(图 15.34)。

                                                                                                                                                                                                                                                                                                                                                                                                      Refer to Figure 15.21 for the related context, class hierarchy, and example for sequence diagrams. As in the sequence diagram case, multiple communication diagrams can be used to show each concrete polymorphic case (Figure 15.34).

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.34.一种在通信图中对多态情况进行建模的方法。



                                                                                                                                                                                                                                                                                                                                                                                                      异步和同步调用

                                                                                                                                                                                                                                                                                                                                                                                                      Asynchronous and Synchronous Calls

                                                                                                                                                                                                                                                                                                                                                                                                      与序列图一样,异步调用用棒状箭头显示;带有实心箭头的 synchronous 调用(参见图 15.35)。

                                                                                                                                                                                                                                                                                                                                                                                                      As in sequence diagrams, asynchronous calls are shown with a stick arrow; synchronous calls with a filled arrow (see Figure 15.35).

                                                                                                                                                                                                                                                                                                                                                                                                      图 15.35.通信图中的异步调用。



                                                                                                                                                                                                                                                                                                                                                                                                        第 16 章.UML 类图

                                                                                                                                                                                                                                                                                                                                                                                                        Chapter 16. UML Class Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                        迭代是人之常情,递归是神圣的。

                                                                                                                                                                                                                                                                                                                                                                                                        匿名

                                                                                                                                                                                                                                                                                                                                                                                                        To iterate is human, to recurse, divine.

                                                                                                                                                                                                                                                                                                                                                                                                        anonymous

                                                                                                                                                                                                                                                                                                                                                                                                        目标

                                                                                                                                                                                                                                                                                                                                                                                                        Objectives

                                                                                                                                                                                                                                                                                                                                                                                                        • 为常用的 UML 类图表示法提供参考。

                                                                                                                                                                                                                                                                                                                                                                                                        • Provide a reference for frequently used UML class diagram notation.



                                                                                                                                                                                                                                                                                                                                                                                                          介绍

                                                                                                                                                                                                                                                                                                                                                                                                          Introduction

                                                                                                                                                                                                                                                                                                                                                                                                          UML 包括用于说明类、接口及其关联的类图。它们用于静态对象建模。我们已经在域建模时介绍并使用了这个 UML 图,从概念的角度应用了类图。本章总结了更多的符号,无论从哪个角度(概念或软件)来看。与前面的交互图章节一样,这是一个参考

                                                                                                                                                                                                                                                                                                                                                                                                          The UML includes class diagrams to illustrate classes, interfaces, and their associations. They are used for static object modeling. We've already introduced and used this UML diagram while domain modeling, applying class diagrams in a conceptual perspective. This chapter summarizes more of the notation, irrespective of the perspective (conceptual or software). As with the prior interaction diagram chapter, this is a reference.

                                                                                                                                                                                                                                                                                                                                                                                                          后续章节将重点介绍一个更重要的问题:OO 设计中的关键原则是什么?这些章节应用 UML 交互和类图来帮助解释和演示对象设计。因此,首先浏览本章很有用,但无需记住所有这些低级细节!

                                                                                                                                                                                                                                                                                                                                                                                                          Subsequent chapters focus on a more important question: What are key principles in OO design? Those chapters apply UML interaction and class diagrams to help explain and demonstrate object design. Hence, it's useful to first skim this chapter, but there's no need to memorize all these low-level details!

                                                                                                                                                                                                                                                                                                                                                                                                            16.1. 应用 UML:公共类图表示法

                                                                                                                                                                                                                                                                                                                                                                                                            16.1. Applying UML: Common Class Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                            许多高频类图表示法可以用一个图来总结(和理解):

                                                                                                                                                                                                                                                                                                                                                                                                            Much of the high-frequency class diagram notation can be summarized (and understood) in one figure:

                                                                                                                                                                                                                                                                                                                                                                                                            图 16.1 中的大多数元素都是可选的(例如,+/- 可见性、参数、区间)。建模者根据上下文和阅读器或 UML 工具的需要来绘制、显示或隐藏它们。

                                                                                                                                                                                                                                                                                                                                                                                                            Most elements in Figure 16.1 are optional (e.g., +/- visibility, parameters, compartments). Modelers draw, show or hide them depending on context and the needs of the reader or UML tool.

                                                                                                                                                                                                                                                                                                                                                                                                            图 16.1.常见的 UML 类图表示法。



                                                                                                                                                                                                                                                                                                                                                                                                            注意

                                                                                                                                                                                                                                                                                                                                                                                                            Note

                                                                                                                                                                                                                                                                                                                                                                                                            与此处显示的各种 UML 类图元素相关的 OOA/D 含义和建模技巧分布在案例研究章节中。您将在此处和索引中找到对 OOA/D 概念的交叉引用。

                                                                                                                                                                                                                                                                                                                                                                                                            The OOA/D implications and modeling tips associated with the various UML class diagram elements shown here are distributed throughout the case study chapters. You will find cross-references to the OOA/D concepts are provided here and in the index.



                                                                                                                                                                                                                                                                                                                                                                                                            例如,本章总结了 UML 关联类表示法,但不解释 OOA/D 建模上下文。许多 notation 元素也是如此。

                                                                                                                                                                                                                                                                                                                                                                                                            For example, this chapter summarizes UML association class notation, but doesn't explain the OOA/D modeling context. Likewise with many of the notation elements.

                                                                                                                                                                                                                                                                                                                                                                                                            应用协会类522

                                                                                                                                                                                                                                                                                                                                                                                                            applying association classes p. 522



                                                                                                                                                                                                                                                                                                                                                                                                              16.2. 定义:设计类图

                                                                                                                                                                                                                                                                                                                                                                                                              16.2. Definition: Design Class Diagram

                                                                                                                                                                                                                                                                                                                                                                                                              正如我们所探索的,同一个 UML 图可以在多个透视图中使用(图 16.2)。从概念的角度来看,类图可用于可视化域模型。为了进行讨论,我们还需要一个独特的术语来阐明何时在软件或设计角度中使用类图。用于此目的的一个常见建模术语是设计类图DCD),我将在后面的章节中经常使用它。在 UP 中,所有 DCD 的集合构成了设计模型的一部分。设计模型的其他部分包括 UML 交互和包图。

                                                                                                                                                                                                                                                                                                                                                                                                              As we've explored, the same UML diagram can be used in multiple perspectives (Figure 16.2). In a conceptual perspective the class diagram can be used to visualize a domain model. For discussion, we also need a unique term to clarify when the class diagram is used in a software or design perspective. A common modeling term for this purpose is design class diagram (DCD), which I'll use regularly in later chapters. In the UP, the set of all DCDs form part of the Design Model. Other parts of the Design Model include UML interaction and package diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                              图 16.2.UML 类图的两个角度。



                                                                                                                                                                                                                                                                                                                                                                                                                16.3. 定义:分类器

                                                                                                                                                                                                                                                                                                                                                                                                                16.3. Definition: Classifier

                                                                                                                                                                                                                                                                                                                                                                                                                UML 分类器是“描述行为和结构特征的模型元素”[OMG03b]。分类器也可以是专用的。它们是 UML 的许多元素的泛化,包括类、接口、用例和参与者。在类图中,两个最常见的分类器是常规类和接口。

                                                                                                                                                                                                                                                                                                                                                                                                                A UML classifier is "a model element that describes behavioral and structure features" [OMG03b]. Classifiers can also be specialized. They are a generalization of many of the elements of the UML, including classes, interfaces, use cases, and actors. In class diagrams, the two most common classifiers are regular classes and interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                  16.4. 显示 UML 属性的方法:属性文本和关联线

                                                                                                                                                                                                                                                                                                                                                                                                                  16.4. Ways to Show UML Attributes: Attribute Text and Association Lines

                                                                                                                                                                                                                                                                                                                                                                                                                  分类器的属性(在 UML 中也称为结构属性[1])以多种方式显示:

                                                                                                                                                                                                                                                                                                                                                                                                                  Attributes of a classifier (also called structural properties in the UML[1]) are shown several ways:

                                                                                                                                                                                                                                                                                                                                                                                                                  [1] 通常缩写为“属性”,其缺点是与 UML 属性的更一般定义相比会产生歧义(第 259 页)。

                                                                                                                                                                                                                                                                                                                                                                                                                  [1] Often shortened to "property" with the disadvantage of causing ambiguity versus the more general definition of a UML property (p. 259).

                                                                                                                                                                                                                                                                                                                                                                                                                  • 属性文本表示法,例如 currentSale : Sale。

                                                                                                                                                                                                                                                                                                                                                                                                                  • attribute text notation, such as currentSale : Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                  • 关联线表示法

                                                                                                                                                                                                                                                                                                                                                                                                                  • association line notation

                                                                                                                                                                                                                                                                                                                                                                                                                  • 两者一起

                                                                                                                                                                                                                                                                                                                                                                                                                  • both together

                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.3 显示了这些表示法,用于表示 Register 对象具有一个 Sale 对象的属性(引用)。

                                                                                                                                                                                                                                                                                                                                                                                                                  Figure 16.3 shows these notations being used to indicate that a Register object has an attribute (a reference to) one Sale object.

                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.3.UML 属性的属性文本与关联线表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                  属性文本表示法的完整格式为:

                                                                                                                                                                                                                                                                                                                                                                                                                  The full format of the attribute text notation is:

                                                                                                                                                                                                                                                                                                                                                                                                                  可见性名称 : 类型 multiplicity = default {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                  visibility name : type multiplicity = default {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                  此外,UML 允许将任何其他编程语言语法用于属性声明,只要通知读者或工具即可。

                                                                                                                                                                                                                                                                                                                                                                                                                  Also, the UML allows any other programming language syntax to be used for the attribute declaration, as long as the reader or tool are notified.

                                                                                                                                                                                                                                                                                                                                                                                                                  如图 16.1 所示,可见性标记包括 + (public)、- (private) 等。

                                                                                                                                                                                                                                                                                                                                                                                                                  As indicated in Figure 16.1, visibility marks include + (public), - (private), and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 如果未提供可见性,则通常假定属性为 private。

                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: Attributes are usually assumed private if no visibility is given.

                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,在图 16.3 中,此 attribute-as-association 行具有以下样式:

                                                                                                                                                                                                                                                                                                                                                                                                                  Notice in Figure 16.3 that this attribute-as-association line has the following style:

                                                                                                                                                                                                                                                                                                                                                                                                                  • 一个从源 (Register) 指向目标 (Sale) 对象的可导航性箭头,指示 Register 对象的属性为 1 Sale

                                                                                                                                                                                                                                                                                                                                                                                                                  • a navigability arrow pointing from the source (Register) to target (Sale) object, indicating a Register object has an attribute of one Sale

                                                                                                                                                                                                                                                                                                                                                                                                                  • 目标端的重数,但不是源端的重数

                                                                                                                                                                                                                                                                                                                                                                                                                  • a multiplicity at the target end, but not the source end

                                                                                                                                                                                                                                                                                                                                                                                                                  • rolenamecurrentSale) 仅在目标端显示属性名称

                                                                                                                                                                                                                                                                                                                                                                                                                  • a rolename (currentSale) only at the target end to show the attribute name

                                                                                                                                                                                                                                                                                                                                                                                                                  • 无关联名称

                                                                                                                                                                                                                                                                                                                                                                                                                  • no association name

                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 将属性显示为关联时,请在 DCD 中遵循 UML 规范建议的此样式。确实,UML 元模型也允许在端(例如,图 16.3 中的 Register 端)使用多重性和角色名,也允许使用关联名称,但它们在 DCD 的上下文中通常没有用。

                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: When showing attributes-as-associations, follow this style in DCDs, which is suggested by the UML specification. It is true that the UML metamodel also allows multiplicity and rolenames at the source end (e.g., the Register end in Figure 16.3), and also an association name, but they are not usually useful in the context of a DCD.

                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 另一方面,当将类图用于域模型时,确实会显示关联名称,但会避免使用导航箭头,因为域模型不是软件视角。参见图 16.4

                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: On the other hand, when using class diagrams for a domain model do show association names but avoid navigation arrows, as a domain model is not a software perspective. See Figure 16.4.

                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.4.关联符号中的惯用语在不同角度的用法。



                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,这不是一种新的关联表示法。这与在将类图应用于域建模时探索的关联的 UML 表示法相同,第 149 页。这是对在软件角度 DCD 上下文中使用的符号的详细说明。

                                                                                                                                                                                                                                                                                                                                                                                                                  Note that this is not a new kind of association notation. It's the same UML notation for associations explored while applying class diagrams to domain modeling, on p. 149. This is an elaboration of the notation for use in the context of a software perspective DCD.

                                                                                                                                                                                                                                                                                                                                                                                                                  指南:何时对属性使用属性文本与关联线?

                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: When to Use Attribute Text versus Association Lines for Attributes?

                                                                                                                                                                                                                                                                                                                                                                                                                  这个问题首先在第 164 页的域建模上下文中进行了探讨。回顾一下,数据类型是指唯一标识不重要的对象。常见数据类型是面向原始类型的类型,例如:

                                                                                                                                                                                                                                                                                                                                                                                                                  This question was first explored in the context of domain modeling on p. 164. To review, a data type refers to objects for which unique identity is not important. Common data types are primitive-oriented types such as:

                                                                                                                                                                                                                                                                                                                                                                                                                  • 布尔值、日期(或日期时间)、数字、字符、字符串(文本)、时间、地址、颜色、几何(点、矩形)、电话号码、社会保险号、通用产品代码 (UPC)、SKU、邮政编码、枚举类型

                                                                                                                                                                                                                                                                                                                                                                                                                  • Boolean, Date (or DateTime), Number, Character, String (Text), Time, Address, Color, Geometrics (Point, Rectangle), Phone Number, Social Security Number, Universal Product Code (UPC), SKU, ZIP or postal codes, enumerated types

                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 对数据类型对象使用属性文本表示法,对其他对象使用关联线表示法。两者在语义上是相等的,但是在图中显示与另一个类框的关联线(如图 16.3 所示)可以在视觉上强调它吸引眼球,强调图上对象类之间的联系。参见图 16.5 以获取对比示例。

                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: Use the attribute text notation for data type objects and the association line notation for others. Both are semantically equal, but showing an association line to another class box in the diagram (as in Figure 16.3) gives visual emphasisit catches the eye, emphasizing the connection between the class of objects on the diagram. See Figure 16.5 for contrasting examples.

                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.5.应用准则以两种表示法显示属性。



                                                                                                                                                                                                                                                                                                                                                                                                                  同样,这些不同的样式仅存在于 UML 表面表示法中;在代码中,它们归结为同一事物:图 16.5Register 类具有三个属性。例如,在 Java 中:

                                                                                                                                                                                                                                                                                                                                                                                                                  Again, these different styles exist only in the UML surface notation; in code, they boil down to the same thingthe Register class of Figure 16.5 has three attributes. For example, in Java:

                                                                                                                                                                                                                                                                                                                                                                                                                  public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                  private int id;
                                                                                                                                                                                                                                                                                                                                                                                                                  private Sale currentSale;
                                                                                                                                                                                                                                                                                                                                                                                                                  private Store location;
                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                  public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                  private int id;
                                                                                                                                                                                                                                                                                                                                                                                                                  private Sale currentSale;
                                                                                                                                                                                                                                                                                                                                                                                                                  private Store location;
                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                  关联端的 UML 表示法

                                                                                                                                                                                                                                                                                                                                                                                                                  The UML Notation for an Association End

                                                                                                                                                                                                                                                                                                                                                                                                                  如前所述,关联的末尾可以具有可导航性箭头。它还可以包括一个可选的 rolename (正式名称,一个关联结束名称) 来指示属性名称。当然,关联端也可能显示重数值,如前面第 153 页所探讨的那样,例如 '*' 或 '0..1'。请注意,在图 16.3 中,角色名 currentSale 用于表示属性名称。

                                                                                                                                                                                                                                                                                                                                                                                                                  As discussed, the end of an association can have a navigability arrow. It can also include an optional rolename (officially, an association end name) to indicate the attribute name. And of course, the association end may also show a multiplicity value, as explored earlier on p. 153, such as '*' or '0..1'. Notice in Figure 16.3 that the rolename currentSale is used to indicate the attribute name.

                                                                                                                                                                                                                                                                                                                                                                                                                  如图 16.6 所示,可以使用 {ordered}{ordered, List}属性字符串{ordered} 是一个 UML 定义的关键字,它暗示集合的元素是有序的(悬念构建......另一个相关关键字是 {unique},表示一组唯一元素。

                                                                                                                                                                                                                                                                                                                                                                                                                  And as shown in Figure 16.6, a property string such as {ordered} or {ordered, List} is possible. {ordered} is a UML-defined keyword that implies the elements of the collection are (the suspense builds…) ordered. Another related keyword is {unique}, implying a set of unique elements.

                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.6.在 UML 中显示集合属性的两种方法。



                                                                                                                                                                                                                                                                                                                                                                                                                  关键字 {List} 表明 UML 还支持用户定义的关键字。我定义 {List} 表示集合属性 lineItems 将通过实现 List 接口的对象来实现。

                                                                                                                                                                                                                                                                                                                                                                                                                  The keyword {List} illustrates that the UML also supports user-defined keywords. I define {List} to mean the collection attribute lineItems will be implemented with an object implementing the List interface.

                                                                                                                                                                                                                                                                                                                                                                                                                  如何使用属性文本和关联行显示集合属性?

                                                                                                                                                                                                                                                                                                                                                                                                                  How to Show Collection Attributes with Attribute Text and Association Lines?

                                                                                                                                                                                                                                                                                                                                                                                                                  假设 Sale 软件对象包含许多 SalesLineItem 对象的 List(一种集合的接口)。例如,在 Java 中:

                                                                                                                                                                                                                                                                                                                                                                                                                  Suppose that a Sale software object holds a List (an interface for a kind of collection) of many SalesLineItem objects. For example, in Java:

                                                                                                                                                                                                                                                                                                                                                                                                                  public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                  private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                              new ArrayList<SalesLineItem>();
                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                  public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                  private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                              new ArrayList<SalesLineItem>();
                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.6 显示了在类图中说明集合属性的两种方法。

                                                                                                                                                                                                                                                                                                                                                                                                                  Figure 16.6 shows two ways to illustrate a collection attribute in class diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                  另请注意属性字符串的可选使用,例如 {ordered}

                                                                                                                                                                                                                                                                                                                                                                                                                  Notice also the optional use of property strings such as {ordered}.

                                                                                                                                                                                                                                                                                                                                                                                                                    16.5. 注释符号:注释、注释、约束和方法体

                                                                                                                                                                                                                                                                                                                                                                                                                    16.5. Note Symbols: Notes, Comments, Constraints, and Method Bodies

                                                                                                                                                                                                                                                                                                                                                                                                                    注意符号可用于任何 UML 图,但在类图上尤其常见。UML 注释元件显示为狗耳矩形,带有一条虚线指向批注元素;它们已经在整本书中使用过(例如,图 16.6)。注释符号可以表示多种内容,例如:

                                                                                                                                                                                                                                                                                                                                                                                                                    Note symbols can be used on any UML diagram, but are especially common on class diagrams. A UML note symbol is displayed as a dog-eared rectangle with a dashed line to the annotated element; they've already been used throughout the book (for example, Figure 16.6). A note symbol may represent several things, such as:

                                                                                                                                                                                                                                                                                                                                                                                                                      16.6. 操作和方法

                                                                                                                                                                                                                                                                                                                                                                                                                      16.6. Operations and Methods

                                                                                                                                                                                                                                                                                                                                                                                                                      操作

                                                                                                                                                                                                                                                                                                                                                                                                                      Operations

                                                                                                                                                                                                                                                                                                                                                                                                                      UML 类框的一个隔间显示操作的签名(许多示例请参见图 16.1)。在撰写本文时,操作语法的完整官方格式为:

                                                                                                                                                                                                                                                                                                                                                                                                                      One of the compartments of the UML class box shows the signatures of operations (see Figure 16.1 for many examples). At the time of this writing, the full, official format of the operation syntax is:

                                                                                                                                                                                                                                                                                                                                                                                                                      可见性名称 (parameter-list) {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                      visibility name (parameter-list) {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,没有返回类型元素,这是一个明显的问题,但出于难以理解的原因,它被故意注入到 UML 2 规范中。规范有可能恢复到类似 UML1 的语法,无论如何,许多作者都表明了这种语法,并且 UML 工具将继续支持:

                                                                                                                                                                                                                                                                                                                                                                                                                      Notice there is no return type element, an obvious problem, but purposefully injected into the UML 2 specification for inscrutable reasons. There is a chance that the specification will revert to a UML1-ish syntax, which in any event many authors show and UML tools will continue to support:

                                                                                                                                                                                                                                                                                                                                                                                                                      可见性名称 (parameter-list) : return-type {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                      visibility name (parameter-list) : return-type {property-string}

                                                                                                                                                                                                                                                                                                                                                                                                                      指南: 假设版本包含 return 类型。

                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: Assume the version that includes a return type.

                                                                                                                                                                                                                                                                                                                                                                                                                      指南: 如果未显示可见性,则操作通常被视为公开。

                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: Operations are usually assumed public if no visibility is shown.

                                                                                                                                                                                                                                                                                                                                                                                                                      属性字符串包含任意附加信息,例如,如果操作是抽象的,则可能引发的异常,等等。

                                                                                                                                                                                                                                                                                                                                                                                                                      The property string contains arbitrary additional information, such as exceptions that may be raised, if the operation is abstract, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                      除了官方的 UML 操作语法之外,UML 还允许使用任何编程语言(如 Java)编写操作签名,前提是读者或工具已收到通知。例如,两种表达式都是可能的:

                                                                                                                                                                                                                                                                                                                                                                                                                      In addition to the official UML operation syntax, the UML allows the operation signature to be written in any programming language, such as Java, assuming the reader or tool is notified. For example, both expressions are possible:

                                                                                                                                                                                                                                                                                                                                                                                                                      + getPlayer( name : String ) : Player {exception IOException}
                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                      public Player getPlayer( String name ) throws IOException
                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                      + getPlayer( name : String ) : Player {exception IOException}
                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                      public Player getPlayer( String name ) throws IOException
                                                                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                      操作不是方法。UML 操作是一个声明,具有名称、参数、返回类型、异常列表,可能还有一组前置条件和后置条件的约束。但是,它不是一个实现,而是方法就是实现。当我们探索操作契约(第 181 页)时,用 UML 术语来说,我们正在探索 UML 操作的约束定义,如第 191 页所讨论的那样。

                                                                                                                                                                                                                                                                                                                                                                                                                      An operation is not a method. A UML operation is a declaration, with a name, parameters, return type, exceptions list, and possibly a set of constraints of pre-and post-conditions. But, it isn't an implementationrather, methods are implementations. When we explored operation contracts (p. 181), in UML terms we were exploring the definition of constraints for UML operations, as was discussed on p. 191.

                                                                                                                                                                                                                                                                                                                                                                                                                      如何在类图中显示方法?

                                                                                                                                                                                                                                                                                                                                                                                                                      How to Show Methods in Class Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                                      UML 方法是操作的实现;如果定义了约束,则该方法必须满足这些约束。一种方法可以用多种方式进行说明,包括:

                                                                                                                                                                                                                                                                                                                                                                                                                      A UML method is the implementation of an operation; if constraints are defined, the method must satisfy them. A method may be illustrated several ways, including:

                                                                                                                                                                                                                                                                                                                                                                                                                      • 在交互图中,按消息的详细信息和顺序

                                                                                                                                                                                                                                                                                                                                                                                                                      • in interaction diagrams, by the details and sequence of messages

                                                                                                                                                                                                                                                                                                                                                                                                                      • 在类图中,使用 «method» 构造型 UML 注释符号

                                                                                                                                                                                                                                                                                                                                                                                                                      • in class diagrams, with a UML note symbol stereotyped with «method»

                                                                                                                                                                                                                                                                                                                                                                                                                      这两种样式将在后续章节中使用。

                                                                                                                                                                                                                                                                                                                                                                                                                      Both styles will be used in subsequent chapters.

                                                                                                                                                                                                                                                                                                                                                                                                                      图 16.7 应用 UML 注释符号来定义方法主体。

                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 16.7 applies a UML note symbol to define the method body.

                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,当我们使用 UML 注释来显示方法时,我们是在同一个图中混合使用静态视图和动态视图。方法主体(定义动态行为)将动态元素添加到静态类图中。

                                                                                                                                                                                                                                                                                                                                                                                                                      Notice, subtly, that when we use a UML note to show a method, we are mixing static and dynamic views in the same diagram. The method body (which defines dynamic behavior) adds a dynamic element to the static class diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,此样式适用于书籍或文档图表以及工具生成的输出,但对于草图或工具输入来说可能过于繁琐或风格化。工具可能会提供一个弹出窗口,只需输入方法的代码即可。

                                                                                                                                                                                                                                                                                                                                                                                                                      Note that this style is good for book or document diagrams and tool-generated output, but perhaps too fussy or stylized for sketching or tool input. Tools may provide a popup window to simply enter the code for a method.

                                                                                                                                                                                                                                                                                                                                                                                                                      DCD 中的操作问题

                                                                                                                                                                                                                                                                                                                                                                                                                      Operation Issues in DCDs

                                                                                                                                                                                                                                                                                                                                                                                                                      create 操作

                                                                                                                                                                                                                                                                                                                                                                                                                      交互图中的 create 消息通常被解释为 Java 和 C# 等语言中 new 运算符的调用和构造函数调用。在 DCD 中,此创建消息通常会使用语言规则映射到构造函数定义,例如构造函数名称等于类名称(Java、C#、C++ 等)。图 16.1 显示了一个例子,其中 SuperclassFoo 构造函数对 “constructor” 进行了原型化,以便其类别清晰。

                                                                                                                                                                                                                                                                                                                                                                                                                      The create message in an interaction diagram is normally interpreted as the invocation of the new operator and a constructor call in languages such as Java and C#. In a DCD this create message will usually be mapped to a constructor definition, using the rules of the languagesuch as the constructor name equal to the class name (Java, C#, C++, …). Figure 16.1 shows an example, with the SuperclassFoo constructor stereotyped «constructor» so that its category is clear.

                                                                                                                                                                                                                                                                                                                                                                                                                      访问属性的操作

                                                                                                                                                                                                                                                                                                                                                                                                                      访问操作会检索或设置属性,例如 getPricesetPrice。这些运算通常被排除(或过滤)在类图中,因为它们生成的噪声值比很高;对于 n 个属性,可能有 2n 个不感兴趣的 gettersetter 操作。大多数 UML 工具都支持过滤其显示,在绘制墙壁草图时忽略它们尤其常见。

                                                                                                                                                                                                                                                                                                                                                                                                                      Accessing operations retrieve or set attributes, such as getPrice and setPrice. These operations are often excluded (or filtered) from the class diagram because of the high noise-to-value ratio they generate; for n attributes, there may be 2n uninteresting getter and setter operations. Most UML tools support filtering their display, and it's especially common to ignore them while wall sketching.

                                                                                                                                                                                                                                                                                                                                                                                                                        16.7. 关键字

                                                                                                                                                                                                                                                                                                                                                                                                                        16.7. Keywords

                                                                                                                                                                                                                                                                                                                                                                                                                        UML 关键字是用于对模型元素进行分类的文本修饰。例如,将分类器框归类为接口的关键字是(令人震惊的惊喜!«interface»。图 16.1 说明了 «interface» 关键字。第 91 页使用了 “actor” 关键字,将人类简笔画演员图标替换为类框,以模拟计算机系统或机器人演员。

                                                                                                                                                                                                                                                                                                                                                                                                                        A UML keyword is a textual adornment to categorize a model element. For example, the keyword to categorize that a classifier box is an interface is (shocking surprise!) «interface». Figure 16.1 illustrates the «interface» keyword. The «actor» keyword was used on p. 91 to replace the human stick-figure actor icon with a class box to model computer-system or robotic actors.

                                                                                                                                                                                                                                                                                                                                                                                                                        指南: 当我们想要速度、易用性和创造性时,流程建模者通常会将关键字简化为“<interface>”或“<I>”。

                                                                                                                                                                                                                                                                                                                                                                                                                        Guideline: When sketching UMLwhen we want speed, ease, and creative flowmodelers often simplify keywords to something like '<interface>' or '<I>'.

                                                                                                                                                                                                                                                                                                                                                                                                                        大多数关键字以 guillemet (« »)[2] 显示,但有些关键字以大括号显示,例如 {abstract},这是包含 abstract 关键字的约束。通常,当 UML 元素表示它可以具有“属性字符串”时,例如 UML 操作和 UML 关联结束具有一些属性字符串术语将是以大括号格式使用的关键字(有些可能是用户定义的术语)。

                                                                                                                                                                                                                                                                                                                                                                                                                        Most keywords are shown in guillemet (« »)[2] but some are shown in curly braces, such as {abstract}, which is a constraint containing the abstract keyword. In general, when a UML element says it can have a "property string"such as a UML operation and UML association end havesome of the property string terms will be keywords (and some may be user defined terms) used in the curly brace format.

                                                                                                                                                                                                                                                                                                                                                                                                                        [2] 请注意,在 UML 1 中,guillemet (« ») 仅用于刻板印象。在 UML 2 中,guillemets 用于关键字和构造型。

                                                                                                                                                                                                                                                                                                                                                                                                                        [2] Note that in UML 1, guillemet (« ») were only used for stereotypes. In UML 2, guillemets are used for both keywords and stereotypes.



                                                                                                                                                                                                                                                                                                                                                                                                                        图 16.1 说明了 «interface» 和 {abstract} 关键字。

                                                                                                                                                                                                                                                                                                                                                                                                                        Figure 16.1 illustrates both the «interface» and {abstract} keywords.

                                                                                                                                                                                                                                                                                                                                                                                                                        一些预定义的 UML 关键字示例包括:[3]

                                                                                                                                                                                                                                                                                                                                                                                                                        A few sample predefined UML keywords include:[3]

                                                                                                                                                                                                                                                                                                                                                                                                                        [3] 有很多关键词。有关详细信息,请参阅 UML 规范。

                                                                                                                                                                                                                                                                                                                                                                                                                        [3] There are many keywords. Refer to the UML specification for details.

                                                                                                                                                                                                                                                                                                                                                                                                                        关键词

                                                                                                                                                                                                                                                                                                                                                                                                                        Keyword

                                                                                                                                                                                                                                                                                                                                                                                                                        意义

                                                                                                                                                                                                                                                                                                                                                                                                                        Meaning

                                                                                                                                                                                                                                                                                                                                                                                                                        示例用法

                                                                                                                                                                                                                                                                                                                                                                                                                        Example Usage

                                                                                                                                                                                                                                                                                                                                                                                                                        «演员»

                                                                                                                                                                                                                                                                                                                                                                                                                        «actor»

                                                                                                                                                                                                                                                                                                                                                                                                                        classifier 是一个 actor

                                                                                                                                                                                                                                                                                                                                                                                                                        classifier is an actor

                                                                                                                                                                                                                                                                                                                                                                                                                        在类图中,上述分类器名称

                                                                                                                                                                                                                                                                                                                                                                                                                        in class diagram, above classifier name

                                                                                                                                                                                                                                                                                                                                                                                                                        «接口»

                                                                                                                                                                                                                                                                                                                                                                                                                        «interface»

                                                                                                                                                                                                                                                                                                                                                                                                                        classifier 是一个接口

                                                                                                                                                                                                                                                                                                                                                                                                                        classifier is an interface

                                                                                                                                                                                                                                                                                                                                                                                                                        在类图中,上述分类器名称

                                                                                                                                                                                                                                                                                                                                                                                                                        in class diagram, above classifier name

                                                                                                                                                                                                                                                                                                                                                                                                                        {摘要}

                                                                                                                                                                                                                                                                                                                                                                                                                        {abstract}

                                                                                                                                                                                                                                                                                                                                                                                                                        抽象元素;无法实例化

                                                                                                                                                                                                                                                                                                                                                                                                                        abstract element; can't be instantiated

                                                                                                                                                                                                                                                                                                                                                                                                                        在类图中,在 Classifier Name 或 Operation Name 之后

                                                                                                                                                                                                                                                                                                                                                                                                                        in class diagrams, after classifier name or operation name

                                                                                                                                                                                                                                                                                                                                                                                                                        {订购}

                                                                                                                                                                                                                                                                                                                                                                                                                        {ordered}

                                                                                                                                                                                                                                                                                                                                                                                                                        一组对象具有一些强制顺序

                                                                                                                                                                                                                                                                                                                                                                                                                        a set of objects have some imposed order

                                                                                                                                                                                                                                                                                                                                                                                                                        在类图中,在关联端

                                                                                                                                                                                                                                                                                                                                                                                                                        in class diagrams, at an association end



                                                                                                                                                                                                                                                                                                                                                                                                                          16.8. 刻板印象、配置文件和标签

                                                                                                                                                                                                                                                                                                                                                                                                                          16.8. Stereotypes, Profiles, and Tags

                                                                                                                                                                                                                                                                                                                                                                                                                          与关键字一样,刻板印象也用 guillemets 符号表示[4],例如 «authorship»。但是,它们不是关键字,这可能会令人困惑。构造型表示对现有建模概念的改进,在 UML 配置文件中非正式地定义,它是相关构造型、标记和约束的集合,用于将 UML 专门用于特定域或平台,例如用于项目管理或数据建模的 UML 配置文件。

                                                                                                                                                                                                                                                                                                                                                                                                                          As with keywords, stereotypes are shown with guillemets symbols[4], such as «authorship». But, they are not keywords, which can be confusing. A stereotype represents a refinement of an existing modeling concept and is defined within a UML profileinformally, a collection of related stereotypes, tags, and constraints to specialize the use of the UML for a specific domain or platform, such as a UML profile for project management or for data modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                          [4] Guillemets 是特殊的字符括号,在法语排版中用于表示引号而广为人知。印刷困难的工具供应商经常用两个尖括号 ('<< >>') 代替更优雅的 '« »'。

                                                                                                                                                                                                                                                                                                                                                                                                                          [4] Guillemets are special single-character brackets most widely known by their use in French typography to indicate a quote. Typographically challenged tool vendors often substitute two angle brackets ('<< >>') for the more elegant '« »'.

                                                                                                                                                                                                                                                                                                                                                                                                                          UML 预定义了许多原型[5],例如 «destroy»(用于序列图),也允许用户定义的原型。因此,刻板印象在 UML 中提供了一种扩展机制

                                                                                                                                                                                                                                                                                                                                                                                                                          The UML predefines many stereotypes[5], such as «destroy» (used on sequence diagrams), and also allows user-defined ones. Thus, stereotypes provide an extension mechanism in the UML.

                                                                                                                                                                                                                                                                                                                                                                                                                          [5] 请参阅 UML 规范。

                                                                                                                                                                                                                                                                                                                                                                                                                          [5] See the UML specification.

                                                                                                                                                                                                                                                                                                                                                                                                                          例如,图 16.8 显示了一个 stereotype 声明及其用法。构造型使用 attribute 语法声明一组 tags。当元素(比如 Square 类)用构造型标记时,所有标记都适用于该元素,并且可以为其赋值。

                                                                                                                                                                                                                                                                                                                                                                                                                          For example, Figure 16.8 shows a stereotype declaration, and its use. The stereotype declares a set of tags, using the attribute syntax. When an element (such as the Square class) is marked with a stereotype, all the tags apply to the element, and can be assigned values.

                                                                                                                                                                                                                                                                                                                                                                                                                          图 16.8.刻板印象声明和使用



                                                                                                                                                                                                                                                                                                                                                                                                                            16.9. UML 属性和属性字符串

                                                                                                                                                                                                                                                                                                                                                                                                                            16.9. UML Properties and Property Strings

                                                                                                                                                                                                                                                                                                                                                                                                                            在 UML 中,属性是“表示元素特征的命名值。属性具有语义影响。[OMG03b]。某些属性在 UML 中是预定义的,例如可见性是操作的属性。其他选项可以是用户定义的。

                                                                                                                                                                                                                                                                                                                                                                                                                            In the UML, a property is "a named value denoting a characteristic of an element. A property has semantic impact." [OMG03b]. Some properties are predefined in the UML, such as visibilitya property of an operation. Others can be user-defined.

                                                                                                                                                                                                                                                                                                                                                                                                                            元素的属性可能以多种方式表示,但文本方法是使用 UML 属性字符串 {name1=value1, name2=value2} 格式,例如 {abstract, visibility=public}。某些属性显示时没有值,例如 {abstract};这通常意味着一个布尔属性,即 {abstract=true} 的简写。请注意,{abstract} 既是 constraint 的示例,也是 property 字符串的示例。

                                                                                                                                                                                                                                                                                                                                                                                                                            Properties of elements may be presented in many ways, but a textual approach is to use the UML property string {name1=value1, name2=value2} format, such as {abstract, visibility=public}. Some properties are shown without a value, such as {abstract}; this usually implies a boolean property, shorthand for {abstract=true}. Note that {abstract} is both an example of a constraint and a property string.



                                                                                                                                                                                                                                                                                                                                                                                                                              16.10. 泛化、抽象类、抽象运算

                                                                                                                                                                                                                                                                                                                                                                                                                              16.10. Generalization, Abstract Classes, Abstract Operations

                                                                                                                                                                                                                                                                                                                                                                                                                              UML 中的泛化用一条实线和从子类到超类的粗三角箭头表示(参见图 16.1)。这是什么意思?在 UML 中,引用:

                                                                                                                                                                                                                                                                                                                                                                                                                              Generalization in the UML is shown with a solid line and fat triangular arrow from the subclass to superclass (see Figure 16.1). What does it mean? In the UML, to quote:

                                                                                                                                                                                                                                                                                                                                                                                                                              泛化 更通用的分类器和更具体的分类器之间的分类关系。特定分类器的每个实例也是通用分类器的间接实例。因此,特定分类器间接具有更通用的分类器的特征。[OMG03b]

                                                                                                                                                                                                                                                                                                                                                                                                                              Generalization A taxonomic relationship between a more general classifier and a more specific classifier. Each instance of the specific classifier is also an indirect instance of the general classifier. Thus, the specific classifier indirectly has features of the more general classifier. [OMG03b]

                                                                                                                                                                                                                                                                                                                                                                                                                              这与 OO 编程语言 (OOPL) 继承相同吗?这要看情况。在域模型概念透视类图中,答案是否的。相反,它意味着 superclass 是一个 superset,而 subclass 是一个 subset。另一方面,在 DCD 软件透视类图中,它意味着从超类到子类的 OOPL 继承。

                                                                                                                                                                                                                                                                                                                                                                                                                              Is this the same as OO programming language (OOPL) inheritance? It depends. In a domain model conceptual-perspective class diagram, the answer is no. Rather, it implies the superclass is a superset and the subclass is a subset. On the other hand, in a DCD software-perspective class diagram, it implies OOPL inheritance from the superclass to subclass.

                                                                                                                                                                                                                                                                                                                                                                                                                              如图 16.1 所示,抽象类和操作可以用 {abstract} 标签(在绘制 UML 时很有用)或斜体名称(在 UML 工具中很容易支持)来显示。

                                                                                                                                                                                                                                                                                                                                                                                                                              As shown in Figure 16.1, abstract classes and operations can be shown either with an {abstract} tag (useful when sketching UML) or by italicizing the name (easy to support in a UML tool).

                                                                                                                                                                                                                                                                                                                                                                                                                              相反的情况,不能在子类中覆盖的 final 类和操作用 {leaf} 标签显示。

                                                                                                                                                                                                                                                                                                                                                                                                                              The opposite case, final classes and operations that can't be overridden in subclasses, are shown with the {leaf} tag.

                                                                                                                                                                                                                                                                                                                                                                                                                                16.11. 依赖关系

                                                                                                                                                                                                                                                                                                                                                                                                                                16.11. Dependency

                                                                                                                                                                                                                                                                                                                                                                                                                                依赖关系线可用于任何关系图,但在类关系图和包关系图上尤其常见。UML 包括一个一般的依赖关系,该关系指示 client 元素(任何类型的,包括类、包、用例等)了解另一个 supplier 元素,并且 supplier 的更改可能会影响 client。这是一个广泛的关系!

                                                                                                                                                                                                                                                                                                                                                                                                                                Dependency lines may be used on any diagram, but are especially common on class and package diagrams. The UML includes a general dependency relationship that indicates that a client element (of any kind, including classes, packages, use cases, and so on) has knowledge of another supplier element and that a change in the supplier could affect the client. That's a broad relationship!

                                                                                                                                                                                                                                                                                                                                                                                                                                依赖关系用从客户端到供应商的虚线箭头线表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                Dependency is illustrated with a dashed arrow line from the client to supplier.

                                                                                                                                                                                                                                                                                                                                                                                                                                依赖关系可以看作是耦合的另一种版本,耦合是软件开发中的一个传统术语,当一个元素耦合或依赖于另一个元素时。

                                                                                                                                                                                                                                                                                                                                                                                                                                Dependency can be viewed as another version of coupling, a traditional term in software development when an element is coupled to or depends on another.

                                                                                                                                                                                                                                                                                                                                                                                                                                依赖项有很多种;以下是对象和类图方面的一些常见类型:

                                                                                                                                                                                                                                                                                                                                                                                                                                There are many kinds of dependency; here are some common types in terms of objects and class diagrams:

                                                                                                                                                                                                                                                                                                                                                                                                                                • 具有 supplier 类型的属性

                                                                                                                                                                                                                                                                                                                                                                                                                                • having an attribute of the supplier type

                                                                                                                                                                                                                                                                                                                                                                                                                                • 向供应商发送消息;对供应商的可见性可以是:

                                                                                                                                                                                                                                                                                                                                                                                                                                  • 属性、参数变量、局部变量、全局变量或类可见性(调用 static 或 class 方法)

                                                                                                                                                                                                                                                                                                                                                                                                                                • sending a message to a supplier; the visibility to the supplier could be:

                                                                                                                                                                                                                                                                                                                                                                                                                                  • an attribute, a parameter variable, a local variable, a global variable, or class visibility (invoking static or class methods)

                                                                                                                                                                                                                                                                                                                                                                                                                                • 接收 supplier 类型的参数

                                                                                                                                                                                                                                                                                                                                                                                                                                • receiving a parameter of the supplier type

                                                                                                                                                                                                                                                                                                                                                                                                                                • 供应商是超类或接口

                                                                                                                                                                                                                                                                                                                                                                                                                                • the supplier is a superclass or interface

                                                                                                                                                                                                                                                                                                                                                                                                                                所有这些都可以在 UML 中用依赖关系行显示,但其中一些类型已经有表示依赖关系的特殊行。例如,有一条特殊的 UML 线来显示超类,一条用于显示接口的实现,还有一条用于属性(attribute-as-association 线)。

                                                                                                                                                                                                                                                                                                                                                                                                                                All of these could be shown with a dependency line in the UML, but some of these types already have special lines that suggest the dependency. For example, there's a special UML line to show the superclass, one to show implementation of an interface, and one for attributes (the attribute-as-association line).

                                                                                                                                                                                                                                                                                                                                                                                                                                因此,对于这些情况,使用 dependency 行没有用。例如,在图 16.6 中,Sale 由于关联线而对 SalesLineItems 有某种依赖性。由于这两个元素之间已经有一条关联线,因此添加第二条虚线箭头依赖关系线是多余的。

                                                                                                                                                                                                                                                                                                                                                                                                                                So, for those cases, it is not useful to use the dependency line. For example, in Figure 16.6 a Sale has some kind of dependency on SalesLineItems by virtue of the association line. Since there's already an association line between these two elements, adding a second dashed arrow dependency line is redundant.

                                                                                                                                                                                                                                                                                                                                                                                                                                因此,何时显示依赖关系?

                                                                                                                                                                                                                                                                                                                                                                                                                                Therefore, when to show a dependency?

                                                                                                                                                                                                                                                                                                                                                                                                                                指南: 在类图中,使用依赖关系线来描述对象之间的全局、参数变量、局部变量和静态方法(当调用另一个类的静态方法时)依赖关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline: In class diagrams use the dependency line to depict global, parameter variable, local variable, and static-method (when a call is made to a static method of another class) dependency between objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                例如,下面的 Java 代码显示了 Sale 类中的 updatePriceFor 方法:

                                                                                                                                                                                                                                                                                                                                                                                                                                For example, the following Java code shows an updatePriceFor method in the Sale class:

                                                                                                                                                                                                                                                                                                                                                                                                                                public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                public void updatePriceFor( ProductDescription description )
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                   Money basePrice = description.getPrice();
                                                                                                                                                                                                                                                                                                                                                                                                                                   //…
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                // …
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                public void updatePriceFor( ProductDescription description )
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                   Money basePrice = description.getPrice();
                                                                                                                                                                                                                                                                                                                                                                                                                                   //…
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                // …
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                updatePriceFor 方法接收 ProductDescription 参数对象,然后向其发送 getPrice 消息。因此,Sale 对象具有对 ProductDescription 的参数可见性和消息发送耦合,因此依赖于 ProductDescription。如果后一个类发生更改,则 Sale 类可能会受到影响。这种依赖关系可以显示在类图中(图 16.9)。

                                                                                                                                                                                                                                                                                                                                                                                                                                The updatePriceFor method receives a ProductDescription parameter object and then sends it a getPrice message. Therefore, the Sale object has parameter visibility to the ProductDescription, and message-sending coupling, and thus a dependency on the ProductDescription. If the latter class changed, the Sale class could be affected. This dependency can be shown in a class diagram (Figure 16.9).

                                                                                                                                                                                                                                                                                                                                                                                                                                图 16.9.显示依赖性。



                                                                                                                                                                                                                                                                                                                                                                                                                                另一个示例:以下 Java 代码显示了 Foo 类中的 doX 方法:

                                                                                                                                                                                                                                                                                                                                                                                                                                Another example: The following Java code shows a doX method in the Foo class:

                                                                                                                                                                                                                                                                                                                                                                                                                                public class Foo
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                   System.runFinalization();
                                                                                                                                                                                                                                                                                                                                                                                                                                   //…
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                // …
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                public class Foo
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                   System.runFinalization();
                                                                                                                                                                                                                                                                                                                                                                                                                                   //…
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                // …
                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                doX 方法调用 System 类上的静态方法。因此,Foo 对象对 System 类具有静态方法依赖关系。这种依赖关系可以显示在类图中(图 16.10)。

                                                                                                                                                                                                                                                                                                                                                                                                                                The doX method invokes a static method on the System class. Therefore, the Foo object has a static-method dependency on the System class. This dependency can be shown in a class diagram (Figure 16.10).

                                                                                                                                                                                                                                                                                                                                                                                                                                图 16.10.显示依赖性。



                                                                                                                                                                                                                                                                                                                                                                                                                                依赖项标签

                                                                                                                                                                                                                                                                                                                                                                                                                                Dependency Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                为了显示依赖关系的类型,或帮助工具生成代码,可以使用关键字或构造型标记依赖关系行。[6]图 16.11

                                                                                                                                                                                                                                                                                                                                                                                                                                To show the type of dependency, or to help a tool with code generation, the dependency line can be labeled with keywords or stereotypes.[6] See Figure 16.11.

                                                                                                                                                                                                                                                                                                                                                                                                                                [6] 请参阅 UML 规范以获取许多预定义的依赖项标签。

                                                                                                                                                                                                                                                                                                                                                                                                                                [6] See the UML specification for many predefined dependency labels.

                                                                                                                                                                                                                                                                                                                                                                                                                                图 16.11.UML 中的可选依赖项标签。



                                                                                                                                                                                                                                                                                                                                                                                                                                  16.12. 接口

                                                                                                                                                                                                                                                                                                                                                                                                                                  16.12. Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                  UML 提供了几种显示接口实现的方法,为客户端提供接口,以及接口依赖关系(必需的接口)。在 UML 中,接口实现的正式名称为接口实现。参见图 16.12

                                                                                                                                                                                                                                                                                                                                                                                                                                  The UML provides several ways to show interface implementation, providing an interface to clients, and interface dependency (a required interface). In the UML, interface implementation is formally called interface realization. See Figure 16.12.

                                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.12.在 UML 中显示接口的不同表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                                  套接字表示法是 UML 2 的新功能。指示“Class X requires (uses) interface Y” 而不画一条指向接口 Y 的线是很有用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                  The socket notation is new to UML 2. It's useful to indicate "Class X requires (uses) interface Y" without drawing a line pointing to interface Y.

                                                                                                                                                                                                                                                                                                                                                                                                                                    16.13. 组合 over 聚合

                                                                                                                                                                                                                                                                                                                                                                                                                                    16.13. Composition Over Aggregation

                                                                                                                                                                                                                                                                                                                                                                                                                                    聚合是 UML 中一种模糊的关联,它松散地表示整体部分关系(就像许多普通关联一样)。与 UML 相比,它在 UML 中没有有意义的独特语义,但该术语在 UML 中定义。为什么?引用 Rumbaugh(UML 的最初和关键创建者之一)的话:

                                                                                                                                                                                                                                                                                                                                                                                                                                    Aggregation is a vague kind of association in the UML that loosely suggests whole-part relationships (as do many ordinary associations). It has no meaningful distinct semantics in the UML versus a plain association, but the term is defined in the UML. Why? To quote Rumbaugh (one of the original and key UML creators):

                                                                                                                                                                                                                                                                                                                                                                                                                                    尽管聚合附带的语义很少,但每个人都认为这是必要的(出于不同的原因)。将其视为建模安慰剂。[RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                    In spite of the few semantics attached to aggregation, everybody thinks it is necessary (for different reasons). Think of it as a modeling placebo. [RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                    指南: 因此,遵循 UML 创建者的建议,不要费心在 UML 中使用聚合;相反,在适当的时候使用组合

                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: Therefore, following the advice of UML creators, don't bother to use aggregation in the UML; rather, use composition when appropriate.

                                                                                                                                                                                                                                                                                                                                                                                                                                    组合(也称为复合聚合)是一种强大的全部分聚合,可用于在某些模型中显示。组合关系意味着 1) 部件的实例(例如 Square)一次只属于一个复合实例(例如一个 Board),2) 该部件必须始终属于一个复合部件(没有自由浮动的 Fingers),以及 3) 复合部件负责创建和删除其部件本身创建/删除部件, 或通过与其他对象协作。与此约束相关的是,如果合成被销毁,则必须销毁其部分,或附加到另一个复合合成不允许自由浮动的手指!例如,如果一个实体纸质大富翁游戏板被摧毁,我们认为方块也被摧毁了(概念角度)。同样,在 DCD 软件的角度来看,如果一个软件 Board 对象被销毁,则其软件 Square 对象也会被销毁。

                                                                                                                                                                                                                                                                                                                                                                                                                                    Composition, also known as composite aggregation, is a strong kind of whole-part aggregation and is useful to show in some models. A composition relationship implies that 1) an instance of the part (such as a Square) belongs to only one composite instance (such as one Board) at a time, 2) the part must always belong to a composite (no free-floating Fingers), and 3) the composite is responsible for the creation and deletion of its partseither by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must either be destroyed, or attached to another compositeno free-floating Fingers allowed! For example, if a physical paper Monopoly game board is destroyed, we think of the squares as being destroyed as well (a conceptual perspective). Likewise, if a software Board object is destroyed, its software Square objects are destroyed, in a DCD software perspective.

                                                                                                                                                                                                                                                                                                                                                                                                                                    组合的 UML 表示法是关联线上的实心菱形,位于该线的复合端(参见图 16.13)。

                                                                                                                                                                                                                                                                                                                                                                                                                                    The UML notation for composition is a filled diamond on an association line, at the composite end of the line (see Figure 16.13).

                                                                                                                                                                                                                                                                                                                                                                                                                                    图 16.13.UML 中的组合。



                                                                                                                                                                                                                                                                                                                                                                                                                                    指南: 组合中的关联名称总是隐含着 “Has-part” 的某种变体,因此不必费心显式命名关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: The association name in composition is always implicitly some variation of "Has-part," therefore don't bother to explicitly name the association.

                                                                                                                                                                                                                                                                                                                                                                                                                                      16.14. 约束

                                                                                                                                                                                                                                                                                                                                                                                                                                      16.14. Constraints

                                                                                                                                                                                                                                                                                                                                                                                                                                      约束可用于大多数 UML 图,但在类图中尤其常见。UML 约束是 UML 元素上的限制或条件。它在大括号之间的文本中可视化;例如:{ size >= 0 }。文本可以是自然语言或其他任何内容,例如 UML 的形式规范语言,对象约束语言 (OCL) [WK99]。参见图 16.14

                                                                                                                                                                                                                                                                                                                                                                                                                                      Constraints may be used on most UML diagrams, but are especially common on class diagrams. A UML constraint is a restriction or condition on a UML element. It is visualized in text between braces; for example: { size >= 0 }. The text may be natural language or anything else, such as UML's formal specification language, the Object Constraint Language (OCL) [WK99]. See Figure 16.14.

                                                                                                                                                                                                                                                                                                                                                                                                                                      图 16.14.约束



                                                                                                                                                                                                                                                                                                                                                                                                                                        16.15. 合格关联

                                                                                                                                                                                                                                                                                                                                                                                                                                        16.15. Qualified Association

                                                                                                                                                                                                                                                                                                                                                                                                                                        限定关联具有限定,用于根据限定符键从更大的相关对象集中选择一个对象(或多个对象)。非正式地,从软件的角度来看,它建议通过键查找内容,例如 HashMap 中的对象。例如,如果 ProductCatalog 包含许多 ProductDescriptions,并且每个 ProductDescriptions 都可以通过 itemID 进行选择,那么图 16.15 中的 UML 表示法可以用来描述这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                        A qualified association has a qualifier that is used to select an object (or objects) from a larger set of related objects, based upon the qualifier key. Informally, in a software perspective, it suggests looking things up by a key, such as objects in a HashMap. For example, if a ProductCatalog contains many ProductDescriptions, and each one can be selected by an itemID, then the UML notation in Figure 16.15 can be used to depict this.

                                                                                                                                                                                                                                                                                                                                                                                                                                        图 16.15.UML 中的合格关联。



                                                                                                                                                                                                                                                                                                                                                                                                                                        关于合格关联,有一个微妙的点:多重性的变化。例如,如图 16.15 (a) 与 (b) 相比,限定减少了关联目标端的多重性,通常从多个下降到 1,因为它意味着通常从更大的集合中选择一个实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                        There's one subtle point about qualified associations: the change in multiplicity. For example, as contrasted in Figure 16.15 (a) vs. (b), qualification reduces the multiplicity at the target end of the association, usually down from many to one, because it implies the selection of usually one instance from a larger set.

                                                                                                                                                                                                                                                                                                                                                                                                                                          16.16. 关联类

                                                                                                                                                                                                                                                                                                                                                                                                                                          16.16. Association Class

                                                                                                                                                                                                                                                                                                                                                                                                                                          关联类允许您将关联本身视为一个类,并使用属性、操作和其他功能对其进行建模。例如,如果 Company 雇用了许多 Persons,并使用 Employees 关联进行建模,则可以将关联本身建模为 Employment 类,并使用 startDate 等属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                          An association class allows you treat an association itself as a class, and model it with attributes, operations, and other features. For example, if a Company employs many Persons, modeled with an Employs association, you can model the association itself as the Employment class, with attributes such as startDate.

                                                                                                                                                                                                                                                                                                                                                                                                                                          在 UML 中,它用从关联到 association 类的虚线表示。参见图 16.16

                                                                                                                                                                                                                                                                                                                                                                                                                                          In the UML, it is illustrated with a dashed line from the association to the association class. See Figure 16.16.

                                                                                                                                                                                                                                                                                                                                                                                                                                          图 16.16.UML 中的关联类。



                                                                                                                                                                                                                                                                                                                                                                                                                                            16.17. 单例类

                                                                                                                                                                                                                                                                                                                                                                                                                                            16.17. Singleton Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                            在 OO 设计模式的世界中,有一种模式特别常见,称为 Singleton 模式。稍后将对此进行解释,但该模式的含义是 instantiatednever two 类只有一个实例。换句话说,它是一个 “singleton” 实例。在 UML 图中,这样的类可以在名称隔间的右上角用“1”标记。参见图 16.17

                                                                                                                                                                                                                                                                                                                                                                                                                                            In the world of OO design patterns, there is one that is especially common, called the Singleton pattern. It is explained later, but an implication of the pattern is that there is only one instance of a class instantiatednever two. In other words, it is a "singleton" instance. In a UML diagram, such a class can be marked with a '1' in the upper right corner of the name compartment. See Figure 16.17.

                                                                                                                                                                                                                                                                                                                                                                                                                                            图 16.17.显示一个单一实例。





                                                                                                                                                                                                                                                                                                                                                                                                                                              16.18. 模板类和接口

                                                                                                                                                                                                                                                                                                                                                                                                                                              16.18. Template Classes and Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                              许多语言(Java、C++ 等)都支持模板化类型,也称为模板、参数化类型和泛型(具有不同的变体含义)。[7]它们最常用于集合类的元素类型,例如列表和映射的元素。例如,在 Java 中,假设一个 Board 软件对象包含一个包含许多 SquaresList(一种集合的接口)。而且,实现 List 接口的具体类是 ArrayList

                                                                                                                                                                                                                                                                                                                                                                                                                                              Many languages (Java, C++, …) support templatized types, also known (with shades of variant meanings) as templates, parameterized types, and generics.[7] They are most commonly used for the element type of collection classes, such as the elements of lists and maps. For example, in Java, suppose that a Board software object holds a List (an interface for a kind of collection) of many Squares. And, the concrete class that implements the List interface is an ArrayList:

                                                                                                                                                                                                                                                                                                                                                                                                                                              [7] 模板类的动机包括提高类型安全性和性能。

                                                                                                                                                                                                                                                                                                                                                                                                                                              [7] Motivations for template classes include increased type safety and performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                              public class Board
                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                              private List<Square> squares = new ArrayList<Square>();
                                                                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                              public class Board
                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                              private List<Square> squares = new ArrayList<Square>();
                                                                                                                                                                                                                                                                                                                                                                                                                                              // …
                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                              请注意,List 接口和 ArrayList 类(实现 List 接口)使用元素类型 Square 进行参数化。如何在 UML 中显示模板类和接口?图 16.18 说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                              Notice that the List interface and the ArrayList class (that implements the List interface) are parameterized with the element type Square. How to show template classes and interfaces in the UML? Figure 16.18 illustrates.

                                                                                                                                                                                                                                                                                                                                                                                                                                              图 16.18.UML 中的模板。



                                                                                                                                                                                                                                                                                                                                                                                                                                                16.19. 用户定义的区间

                                                                                                                                                                                                                                                                                                                                                                                                                                                16.19. User-Defined Compartments

                                                                                                                                                                                                                                                                                                                                                                                                                                                除了常见的预定义区间类区间(如名称、属性和操作)之外,还可以将用户定义的区间添加到类框中。图 16.19 显示了一个例子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                In addition to common predefined compartments class compartments such as name, attributes, and operations, user-defined compartments can be added to a class box. Figure 16.19 shows an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                图 16.19.车厢。



                                                                                                                                                                                                                                                                                                                                                                                                                                                  16.20. Active 类

                                                                                                                                                                                                                                                                                                                                                                                                                                                  16.20. Active Class

                                                                                                                                                                                                                                                                                                                                                                                                                                                  活动对象在其自己的执行线程上运行并控制。毫不奇怪,活动对象的类是活动类。在 UML 中,它可能在类框的左侧和右侧用双垂直线显示(图 16.20)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                  An active object runs on and controls its own thread of execution. Not surprisingly, the class of an active object is an active class. In the UML, it may be shown with double vertical lines on the left and right sides of the class box (Figure 16.20).

                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 16.20.UML 中的活动类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                  活动对象 第 238

                                                                                                                                                                                                                                                                                                                                                                                                                                                  active object p. 238



                                                                                                                                                                                                                                                                                                                                                                                                                                                    16.21. 交互和类图之间有什么关系?

                                                                                                                                                                                                                                                                                                                                                                                                                                                    16.21. What's the Relationship Between Interaction and Class Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                                                                    当我们绘制交互图时,动态对象建模的创造性设计过程中会出现一组类及其方法。例如,如果我们从图 16.21 中的(简单解释的)makePayment 序列图开始,我们可以看到类图中的 RegisterSale 类定义显然可以推导出来。

                                                                                                                                                                                                                                                                                                                                                                                                                                                    When we draw interaction diagrams, a set of classes and their methods emerge from the creative design process of dynamic object modeling. For example, if we started with the (trivial for explanation) makePayment sequence diagram in Figure 16.21, we see that a Register and Sale class definition in a class diagram can be obviously derived.

                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 16.21.交互图对类图的影响。



                                                                                                                                                                                                                                                                                                                                                                                                                                                    因此,可以从交互图中生成类图的定义。这表明在绘制类图之前绘制交互图是线性顺序的,但在实践中,尤其是在并行遵循模型的敏捷建模实践时,这些互补的动态和静态视图是同时绘制的。例如,一个 10 分钟,另一个 10 分钟。

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Thus, from interaction diagrams the definitions of class diagrams can be generated. This suggests a linear ordering of drawing interaction diagrams before class diagrams, but in practice, especially when following the agile modeling practice of models in parallel, these complementary dynamic and static views are drawn concurrently. For example, 10 minutes on one, then 10 on the other.

                                                                                                                                                                                                                                                                                                                                                                                                                                                    指南: 一个好的 UML 工具应该自动支持一个关系图中的更改反映在另一个关系图中。如果绘制墙图,则使用一面墙作为交互图,将一面相邻的墙用于类图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: A good UML tool should automatically support changes in one diagram being reflected in the other. If wall sketching, use one wall for interaction diagrams, and an adjacent wall for class diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      第 17 章.GRASP:设计具有职责的对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chapter 17. GRASP: Designing Objects with Responsibilities

                                                                                                                                                                                                                                                                                                                                                                                                                                                      了解职责是良好的面向对象设计的关键。

                                                                                                                                                                                                                                                                                                                                                                                                                                                      马丁·福勒

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Understanding responsibilities is key to good object-oriented design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Martin Fowler

                                                                                                                                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 学习将 GRASP 原则或模式中的五个应用于 OOD。

                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Learn to apply five of the GRASP principles or patterns for OOD.



                                                                                                                                                                                                                                                                                                                                                                                                                                                      本章和下一章对理解核心 OO 设计 (OOD) 有很大帮助。OOD 有时被教授为以下内容的某种变体:

                                                                                                                                                                                                                                                                                                                                                                                                                                                      This chapter and the next contribute significantly to an understanding of core OO design (OOD). OOD is sometimes taught as some variation of the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                      在确定您的需求并创建域模型后,将方法添加到相应的类中,并定义对象之间的消息传递以满足要求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                      After identifying your requirements and creating a domain model, then add methods to the appropriate classes, and define the messaging between the objects to fulfill the requirements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      哎哟!这种模糊的建议对我们没有帮助,因为这涉及到深奥的原则和问题。决定哪些方法属于、对象应该在哪里以及如何交互会产生后果,应该认真对待。掌握 OOD这是其错综复杂的魅力,涉及大量具有多个自由度的软原则。模式可以被命名(重要)、解释和应用,这并不神奇。示例会有所帮助。熟能生惯用。这一小步有帮助:在研究了这些案例研究之后,尝试与合作伙伴一起在墙上重现(凭记忆)大富翁解决方案,并应用信息专家等原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ouch! Such vague advice doesn't help us, because deep principles and issues are involved. Deciding what methods belong where and how objects should interact carries consequences and should be undertaken seriously. Mastering OODand this is its intricate charminvolves a large set of soft principles, with many degrees of freedom. It isn't magicthe patterns can be named (important!), explained, and applied. Examples help. Practice helps. And this small step helps: After studying these case studies, try recreating (from memory) the Monopoly solution on walls with partners, and apply the principles, such as Information Expert.

                                                                                                                                                                                                                                                                                                                                                                                                                                                        17.1. UML 与设计原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                        17.1. UML versus Design Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                        由于 UML 只是一种标准的可视化建模语言,因此了解其细节并不能教你如何在对象中思考这是本书的主题。UML 有时被描述为“设计工具”,但这并不完全正确......

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Since the UML is simply a standard visual modeling language, knowing its details doesn't teach you how to think in objectsthat's a theme of this book. The UML is sometimes described as a "design tool" but that's not quite right…



                                                                                                                                                                                                                                                                                                                                                                                                                                                        软件开发的关键设计工具是受过良好设计原则教育的头脑。它不是 UML 或任何其他技术。

                                                                                                                                                                                                                                                                                                                                                                                                                                                        The critical design tool for software development is a mind well educated in design principles. It is not the UML or any other technology.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          17.2. 对象设计:示例输入、活动和输出

                                                                                                                                                                                                                                                                                                                                                                                                                                                          17.2. Object Design: Example Inputs, Activities, and Outputs

                                                                                                                                                                                                                                                                                                                                                                                                                                                          本节总结了迭代方法中的设计大图示例:

                                                                                                                                                                                                                                                                                                                                                                                                                                                          This section summarizes a big-picture example of design in an iterative method:

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 做了什么? 先前的活动(例如,研讨会)和工件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • What's been done? Prior activities (e.g., workshop) and artifacts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 事物是如何关联的? 先前工件(例如,用例)对 OO 设计的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • How do things relate? Influence of prior artifacts (e.g., use cases) on OO design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 要做多少设计建模,怎么做?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • How much design modeling to do, and how?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 输出是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • What's the output?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          特别是,我希望您了解分析工件与对象设计的关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Especially, I'd like you to understand how the analysis artifacts relate to object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Object Design 的输入是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          What Are Inputs to Object Design?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          让我们从 “process” 输入开始。假设我们是从事 POS NextGen 项目的开发人员,并且以下场景为 true:

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Let's start with "process" inputs. Assume we are developers working on the POS NextGen project, and the following scenario is true:

                                                                                                                                                                                                                                                                                                                                                                                                                                                          第一个为期两天的需求研讨会已经结束。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The first two-day requirements workshop is finished.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          首席架构师和业务人员同意在第一个为期三周的 timeboxed 迭代中实现和测试 Process Sale 的一些场景。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The chief architect and business agree to implement and test some scenarios of Process Sale in the first three-week timeboxed iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          20 个用例中,有 3 个在架构上最重要且具有较高业务价值的用例已经进行了详细分析,当然也包括 Process Sale 用例。(UP 建议,与典型的迭代方法一样,在开始编程之前,只详细分析 10%20% 的需求

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Three of the twenty use casesthose that are the most architecturally significant and of high business valuehave been analyzed in detail, including, of course, the Process Sale use case. (The UP recommends, as typical with iterative methods, analyzing only 10%20% of the requirements in detail before starting to program.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          其他工件已启动:Supplementary Specification、Glossary 和 Domain Model。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Other artifacts have been started: Supplementary Specification, Glossary, and Domain Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          编程实验已经解决了一些棘手的技术问题,比如 Java Swing UI 是否可以在触摸屏上工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Programming experiments have resolved the show-stopper technical questions, such as whether a Java Swing UI will work on a touch screen.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          首席架构师使用 UML 封装图为大规模逻辑架构绘制了一些想法。这是 UP 设计模型的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The chief architect has drawn some ideas for the large-scale logical architecture, using UML package diagrams. This is part of the UP Design Model.



                                                                                                                                                                                                                                                                                                                                                                                                                                                          工件输入及其与对象设计的关系是什么?[1] 图 17.1 和下表对它们进行了总结。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          What are the artifact inputs and their relationship to object design?[1] They are summarized in Figure 17.1 and in the following table.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] 其他工件输入可能包括正在修改的现有系统的设计文档。将现有代码反向工程到 UML 包图中以查看大规模逻辑结构以及一些类和序列图也很有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] Other artifact inputs could include design documents for an existing system being modified. It's also useful to reverse-engineer existing code into UML package diagrams to see the large-scale logical structure and some class and sequence diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 17.1.强调对 OO 设计影响的工件关系。



                                                                                                                                                                                                                                                                                                                                                                                                                                                          用例文本定义了软件对象最终必须支持的可见行为对象旨在“实现”(实现)用例。在 UP 中,这种 OO 设计被称为用例实现,这并不奇怪。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The use case text defines the visible behavior that the software objects must ultimately supportobjects are designed to "realize" (implement) the use cases. In the UP, this OO design is called, not surprisingly, the use case realization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          补充规范定义了我们的对象必须满足的非功能性目标,例如内部化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Supplementary Specification defines the non-functional goals, such as internalization, our objects must satisfy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          系统序列图标识系统操作消息,这些消息是协作对象的交互图上的起始消息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The system sequence diagrams identify the system operation messages, which are the starting messages on our interaction diagrams of collaborating objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          术语表阐明了来自 UI 层的参数或数据、传递到数据库的数据以及特定于商品的详细逻辑或验证要求的详细信息,例如商品 UPC(通用商品代码)的法律格式和验证。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Glossary clarifies details of parameters or data coming in from the UI layer, data being passed to the database, and detailed item-specific logic or validation requirements, such as the legal formats and validation for product UPCs (universal product codes).

                                                                                                                                                                                                                                                                                                                                                                                                                                                          操作协定可以补充用例文本,以阐明软件对象在系统操作中必须实现的目标。后置条件定义详细的成就。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The operation contracts may complement the use case text to clarify what the software objects must achieve in a system operation. The post-conditions define detailed achievements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Domain Model 建议软件体系结构的域层中软件域对象的一些名称和属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Domain Model suggests some names and attributes of software domain objects in the domain layer of the software architecture.



                                                                                                                                                                                                                                                                                                                                                                                                                                                          并非所有这些工件都是必需的。回想一下,在 UP 中,所有元素都是可选的,可能是为了降低一些风险而创建的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Not all of these artifacts are necessary. Recall that in the UP all elements are optional, possibly created to reduce some risk.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Object Design 的活动有哪些?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          What Are Activities of Object Design?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          我们已经准备好摘下分析师的帽子,戴上我们的设计师建模师帽子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          We're ready to take off our analyst hats and put on our designer-modeler hats.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          给定这些输入中的一个或多个,开发人员 1) 立即开始编码(最好是测试优先开发),2) 开始为对象设计进行一些 UML 建模,或 3) 开始使用另一种建模技术,例如 CRC 卡。[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Given one or more of these inputs, developers 1) start immediately coding (ideally with test-first development), 2) start some UML modeling for the object design, or 3) start with another modeling technique, such as CRC cards.[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                          [2] 所有这些方法都根据环境和人的不同而熟练。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          [2] All of these approaches are skillful depending on context and person.



                                                                                                                                                                                                                                                                                                                                                                                                                                                          在 UML 的情况下,真正的重点不是 UML,而是使用一种语言进行可视化建模,这种语言允许我们比仅使用原始文本更深入地进行探索。例如,在这种情况下,我们在一个建模日内同时绘制交互图和互补类图(动态和静态建模)。最重要的是,在绘图(和编码)活动期间,我们应用各种 OO 设计原则,例如 GRASP四人帮 (GoF) 设计模式。执行 OO 设计建模的总体方法将基于责任驱动设计 (RDD) 的隐喻,思考如何将责任分配给协作对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the UML case, the real point is not the UML, but visual modelingusing a language that allows us to explore more visually than we can with just raw text. In this case, for example, we draw both interaction diagrams and complementary class diagrams (dynamic and static modeling) during one modeling day. And most importantly, during the drawing (and coding) activity we apply various OO design principles, such as GRASP and the Gang-of-Four (GoF) design patterns. The overall approach to doing the OO design modeling will be based on the metaphor of responsibility-driven design (RDD), thinking about how to assign responsibilities to collaborating objects.



                                                                                                                                                                                                                                                                                                                                                                                                                                                          GoF 第 435

                                                                                                                                                                                                                                                                                                                                                                                                                                                          GoF p. 435



                                                                                                                                                                                                                                                                                                                                                                                                                                                          RDD 276

                                                                                                                                                                                                                                                                                                                                                                                                                                                          RDD p. 276



                                                                                                                                                                                                                                                                                                                                                                                                                                                          本章和后续章节探讨了应用 RDD、GRASP 和一些 GoF 设计模式的含义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          This and subsequent chapters explore what it means to apply RDD, GRASP, and some of the GoF design patterns.



                                                                                                                                                                                                                                                                                                                                                                                                                                                          在建模日,也许团队以小组形式工作 26 小时,要么在墙壁上工作,要么使用软件建模工具,为设计中困难的、创造性的部分进行不同类型的建模。这可能包括 UI、OO 和使用 UML 绘图的数据库建模、原型制作工具、草图等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          On the modeling day, perhaps the team works in small groups for 26 hours either at the walls or with software modeling tools, doing different kinds of modeling for the difficult, creative parts of the design. This could include UI, OO, and database modeling with UML drawings, prototyping tools, sketches, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          在 UML 绘图过程中,我们采用现实的态度(在敏捷建模中也得到了推广),即我们绘制模型主要是为了理解和交流,而不是为了记录。当然,我们希望一些 UML 图成为代码定义(或使用 UML 工具自动生成代码)的有用输入。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          During UML drawing, we adopt the realistic attitude (also promoted in agile modeling) that we are drawing the models primarily to understand and communicate, not to document. Of course, we expect some of the UML diagrams to be useful input to the definition (or automated code generation with a UML tool) of the code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          周二,在为期三周的 timeboxed 迭代的早期,团队停止建模并戴上程序员的帽子,以避免在编程前过度建模的瀑布心态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          On Tuesdaystill early in the three-week timeboxed iterationthe team stops modeling and puts on programmer hats to avoid a waterfall mentality of over-modeling before programming.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          输出是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          What Are the Outputs?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 17.1 说明了一些输入以及它们与 UML 交互和类图输出的关系。请注意,我们可能会在设计过程中引用这些分析输入;例如,重新阅读用例文本或操作协定,扫描域模型,并查看补充规范。

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Figure 17.1 illustrates some inputs and their relationship to the output of a UML interaction and class diagram. Notice that we may refer to these analysis inputs during design; for example, re-reading the use case text or operation contracts, scanning the domain model, and reviewing the Supplementary Specification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          例如,在建模日期间创建了哪些内容?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          What's been created during the modeling day (for example)?

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 特别是对于对象设计、UML 交互、类和包图,用于我们希望在编码之前探索的设计难点部分

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • specifically for object design, UML interaction, class, and package diagrams for the difficult parts of the design that we wished to explore before coding

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • UI 草图和原型

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • UI sketches and prototypes

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 数据库模型(使用 UML 数据建模配置文件表示法,第 629 页)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • database models (with UML data modeling profile notation p. 629)

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 报表草图和原型

                                                                                                                                                                                                                                                                                                                                                                                                                                                          • report sketches and prototypes

                                                                                                                                                                                                                                                                                                                                                                                                                                                            17.3. 责任和责任驱动设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                            17.3. Responsibilities and Responsibility-Driven Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                            考虑软件对象和更大规模组件设计的一种流行方式[3] 是从职责角色协作的角度来考虑。这是称为责任驱动设计RDD [WM02] 的更大方法的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            A popular way of thinking about the design of software objects and also larger-scale components[3] is in terms of responsibilities, roles, and collaborations. This is part of a larger approach called responsibility-driven design or RDD [WM02].

                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] 从责任的角度思考可以适用于任何规模的软件,从小对象到系统系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] Thinking in terms of responsibilities can apply at any scale of softwarefrom a small object to a system of systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            在 RDD 中,我们认为软件对象具有 responsibilities — 它们所做的事情的抽象。UML 将责任定义为“分类器的合同或义务”[OMG03b]。责任与对象的义务或行为有关。基本上,这些责任分为以下两种类型:知道

                                                                                                                                                                                                                                                                                                                                                                                                                                                            In RDD, we think of software objects as having responsibilitiesan abstraction of what they do. The UML defines a responsibility as "a contract or obligation of a classifier" [OMG03b]. Responsibilities are related to the obligations or behavior of an object in terms of its role. Basically, these responsibilities are of the following two types: doing and knowing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            执行对象的职责包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Doing responsibilities of an object include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 执行某些操作,例如创建对象或执行计算

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • doing something itself, such as creating an object or doing a calculation

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 在其他对象中启动操作

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • initiating action in other objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 控制和协调其他对象中的活动

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • controlling and coordinating activities in other objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                            了解对象的职责包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Knowing responsibilities of an object include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 了解私有封装数据

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • knowing about private encapsulated data

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 了解相关对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • knowing about related objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 了解它可以推导出或计算的事物

                                                                                                                                                                                                                                                                                                                                                                                                                                                            • knowing about things it can derive or calculate

                                                                                                                                                                                                                                                                                                                                                                                                                                                            在对象设计期间,将职责分配给对象类。例如,我可以声明“Sale 负责创建 SalesLineItems”(一个 doing),或者“一个 Sale 负责知道它的总数”(一个知道)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Responsibilities are assigned to classes of objects during object design. For example, I may declare that "a Sale is responsible for creating SalesLineItems" (a doing), or "a Sale is responsible for knowing its total" (a knowing).

                                                                                                                                                                                                                                                                                                                                                                                                                                                            指南: 对于软件领域对象,由于域模型所说明的属性和关联,它通常会激发与 “knowing” 相关的责任。例如,如果域模型 Sale 类具有时间属性,则软件 Sale 类自然知道其时间,因此具有低表示差距的目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Guideline: For software domain objects, the domain model, because of the attributes and associations it illustrates, often inspires the relevant responsibilities related to "knowing." For example, if the domain model Sale class has a time attribute, it's natural by the goal of low representational gap that a software Sale class knows its time.



                                                                                                                                                                                                                                                                                                                                                                                                                                                            将职责转换为类和方法受责任粒度的影响。重大责任需要数百个类和方法。小责任可能采用一种方法。例如,“提供对关系数据库的访问”的责任可能涉及 200 个类和数千个方法,它们打包在一个子系统中。相比之下,“create a Sale” 的责任可能只涉及一个类中的一种方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            The translation of responsibilities into classes and methods is influenced by the granularity of the responsibility. Big responsibilities take hundreds of classes and methods. Little responsibilities might take one method. For example, the responsibility to "provide access to relational databases" may involve two hundred classes and thousands of methods, packaged in a subsystem. By contrast, the responsibility to "create a Sale" may involve only one method in one class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            责任与方法不是一回事,它是一个抽象,但方法履行责任。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            A responsibility is not the same thing as a methodit's an abstractionbut methods fulfill responsibilities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD 还包括协作的理念。责任是通过单独操作或与其他方法和对象协作的方法实现的。例如,Sale 类可以定义一个或多个方法来了解其总数;例如,一个名为 getTotal 的方法。为了履行该职责,Sale 可以与其他对象协作,例如向每个 SalesLineItem 对象发送 getSubtotal 消息,询问其小计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD also includes the idea of collaboration. Responsibilities are implemented by means of methods that either act alone or collaborate with other methods and objects. For example, the Sale class might define one or more methods to know its total; say, a method named getTotal. To fulfill that responsibility, the Sale may collaborate with other objects, such as sending a getSubtotal message to each SalesLineItem object asking for its subtotal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD 是一个隐喻

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD is a Metaphor

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD 是思考 OO 软件设计的一般比喻。将软件对象视为类似于负责与其他人协作完成工作的人员。RDD 导致将 OO 设计视为协作负责对象的社区

                                                                                                                                                                                                                                                                                                                                                                                                                                                            RDD is a general metaphor for thinking about OO software design. Think of software objects as similar to people with responsibilities who collaborate with other people to get work done. RDD leads to viewing an OO design as a community of collaborating responsible objects.



                                                                                                                                                                                                                                                                                                                                                                                                                                                            关键点: GRASP 命名并描述了一些分配职责的基本原则,因此了解支持 RDD 是很有用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Key point: GRASP names and describes some basic principles to assign responsibilities, so it's useful to knowto support RDD.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              17.4. GRASP:基本 OO 设计的方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                              17.4. GRASP: A Methodical Approach to Basic OO Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                              GRASP:具有责任OO 设计的学习辅助工具

                                                                                                                                                                                                                                                                                                                                                                                                                                                              GRASP: A Learning Aid for OO Design with Responsibilities

                                                                                                                                                                                                                                                                                                                                                                                                                                                              可以命名和解释掌握基本对象设计所需的详细原则和推理,为对象分配责任。GRASP 原则或模式是一种学习辅助工具,可帮助您理解基本的对象设计,并以有条不紊、理性、可解释的方式应用设计推理。这种理解和使用设计原则的方法基于分配职责的模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                              It is possible to name and explain the detailed principles and reasoning required to grasp basic object design, assigning responsibilities to objects. The GRASP principles or patterns are a learning aid to help you understand essential object design and apply design reasoning in a methodical, rational, explainable way. This approach to understanding and using design principles is based on patterns of assigning responsibilities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              本章和其他几个章节使用 GRASP 作为工具来帮助掌握 OOD 的基础知识并了解对象设计中的职责分配。

                                                                                                                                                                                                                                                                                                                                                                                                                                                              This chapterand several othersuses GRASP as a tool to help master the basics of OOD and understanding responsibility assignment in object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              了解如何将 GRASP 应用于对象设计是本书的一个关键目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Understanding how to apply GRASP for object design is a key goal of the book.



                                                                                                                                                                                                                                                                                                                                                                                                                                                              因此,GRASP 是相关的,但另一方面,它只是构建和命名原则的学习辅助工具一旦你“掌握”了基本原理,特定的 GRASP 术语(信息专家、创造者等)就不重要了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                              So, GRASP is relevant, but on the other hand, it's just a learning aid to structure and name the principlesonce you "grasp" the fundamentals, the specific GRASP terms (Information Expert, Creator, …) aren't important.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                17.5. 职责图、GRASP 和 UML 图之间有什么联系?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                17.5. What's the Connection Between Responsibilities, GRASP, and UML Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                您可以考虑在编码或建模时为对象分配职责。在 UML 中,绘制交互图成为考虑这些职责(以方法形式实现)的机会。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                You can think about assigning responsibilities to objects while coding or while modeling. Within the UML, drawing interaction diagrams becomes the occasion for considering these responsibilities (realized as methods).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.2 表明 Sale 对象被赋予了创建 Payments 的责任,该任务通过 makePayment 消息具体调用,并使用相应的 makePayment 方法进行处理。此外,履行此职责需要协作来创建 Payment 对象并调用其构造函数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Figure 17.2 indicates that Sale objects have been given a responsibility to create Payments, which is concretely invoked with a makePayment message and handled with a corresponding makePayment method. Furthermore, the fulfillment of this responsibility requires collaboration to create the Payment object and invoke its constructor.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.2.责任和方法是相关的。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,当我们绘制 UML 交互图时,我们正在决定职责分配。本章重点介绍 GRASP 中表达的基本原则,以指导有关分配职责的选择。因此,您可以在绘制 UML 交互图和编码时应用 GRASP 原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Therefore, when we draw a UML interaction diagram, we are deciding on responsibility assignments. This chapter emphasizes fundamental principlesexpressed in GRASPto guide choices about assigning responsibilities. Thus, you can apply the GRASP principles while drawing UML interaction diagrams, and also while coding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  17.6. 什么是 Pattern?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  17.6. What are Patterns?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  经验丰富的 OO 开发人员(和其他软件开发人员)构建了一整套通用原则和惯用解决方案,以指导他们创建软件。这些原则和习语,如果以描述问题和解决方案的结构化格式编纂并命名,则可以称为模式。例如,下面是一个示例模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Experienced OO developers (and other software developers) build up a repertoire of both general principles and idiomatic solutions that guide them in the creation of software. These principles and idioms, if codified in a structured format describing the problem and solution and named, may be called patterns. For example, here is a sample pattern:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图案名称:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Pattern Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  为对象分配责任的基本原则是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What is a basic principle by which to assign responsibilities to objects?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  溶液:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Solution:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将责任分配给具有完成该责任所需信息的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Assign a responsibility to the class that has the information needed to fulfill it.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在 OO 设计中,模式是可以应用于新上下文的问题和解决方案的命名描述;理想情况下,模式会建议我们如何在不同情况下应用其解决方案,并考虑力量和权衡。给定特定问题类别的许多模式指导将责任分配给对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In OO design, a pattern is a named description of a problem and solution that can be applied to new contexts; ideally, a pattern advises us on how to apply its solution in varying circumstances and considers the forces and trade-offs. Many patterns, given a specific category of problem, guide the assignment of responsibilities to objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  最简单的是,一个好的模式是一个命名的、众所周知的问题/解决方案对,它可以应用于新的上下文,并提供有关如何在新情况下应用它的建议,并讨论其权衡、实现、变化等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Most simply, a good pattern is a named and well-known problem/solution pair that can be applied in new contexts, with advice on how to apply it in novel situations and discussion of its trade-offs, implementations, variations, and so forth.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图案有名字重要!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Patterns Have NamesImportant!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  软件开发是一个年轻的领域。年轻的领域缺乏其原则的知名名称,这使得沟通和教育变得困难。模式具有名称,例如 Information ExpertAbstract Factory。命名模式、设计理念或原则具有以下优点:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software development is a young field. Young fields lack well-established names for their principlesand that makes communication and education difficult. Patterns have names, such as Information Expert and Abstract Factory. Naming a pattern, design idea, or principle has the following advantages:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 它支持分块并将该概念纳入我们的理解和记忆中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • It supports chunking and incorporating that concept into our understanding and memory.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 它促进了沟通。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • It facilitates communication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当一个模式被命名并广泛发布时,我们都同意使用这个名字,我们可以用更短的句子(或更短的图表)来讨论一个复杂的设计思想,这是一种抽象的优点。考虑以下两个软件开发人员之间的讨论,使用模式名称词汇表:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  When a pattern is named and widely publishedand we all agree to use the namewe can discuss a complex design idea in shorter sentences (or shorter diagrams), a virtue of abstraction. Consider the following discussion between two software developers, using a vocabulary of pattern names:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  吉尔:“嘿 Jack,对于持久化子系统,让我们使用 Facade 公开服务。我们将使用 Abstract Factory 进行 Mapper,使用 Proxies 进行延迟具体化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Jill: "Hey Jack, for the persistence subsystem, let's expose the services with a Facade. We'll use an Abstract Factory for Mappers, and Proxies for lazy materialization."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  千斤顶:“你刚才他妈说了什么?!?”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Jack: "What the hell did you just say?!?"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  吉尔:“来,读这个......”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Jill: "Here, read this…"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “New Pattern”是一个矛盾的说法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'New Pattern' is an Oxymoron

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如果新模式描述了一个新想法,则应将其视为矛盾修辞法。“模式”一词本身就暗示了一个长期重复的事情。设计模式的重点不是表达新的设计思想。恰恰相反,伟大的模式试图将现有的久经考验的知识、习语和原则编纂成文;越是经过磨练、越古老、越广泛使用越好。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  New pattern should be considered an oxymoron if it describes a new idea. The very term "pattern" suggests a long-repeating thing. The point of design patterns is not to express new design ideas. Quite the oppositegreat patterns attempt to codify existing tried-and-true knowledge, idioms, and principles; the more honed, old, and widely used, the better.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  因此,GRASP 模式并不陈述新的想法;它们命名并编纂了广泛使用的基本原则。对于 OO 设计专家来说,GRASP 模式的想法如果不是名字的话,会显得基础和熟悉。这就是重点!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Consequently, the GRASP patterns don't state new ideas; they name and codify widely used basic principles. To an OO design expert, the GRASP patternsby idea if not by namewill appear fundamental and familiar. That's the point!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Gang-of-Four Design Patterns 书籍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Gang-of-Four Design Patterns Book

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在软件中命名模式的想法来自 1980 年代中期的 Kent Beck(也因极限编程而闻名)[4]。然而,1994 年是模式、OO 设计和软件设计书籍历史上的一个重要里程碑:畅销且极具影响力的书籍 Design Patterns [GHJV95][5]由 Gamma、Helm、Johnson 和 Vlissides 出版并撰写。这本书被认为是设计模式书籍的“圣经”,它描述了 OO 设计的 23 种模式,名称包括 StrategyAdapter。这 23 个模式由四个人编写,因此被称为 Gang of Four[6](或 GoF)设计模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The idea of named patterns in software comes from Kent Beck (also of Extreme Programming fame) in the mid 1980s.[4] However, 1994 was a major milestone in the history of patterns, OO design, and software design books: The massive-selling and hugely influential book Design Patterns [GHJV95][5] was published, authored by Gamma, Helm, Johnson, and Vlissides. The book, considered the "Bible" of design pattern books, describes 23 patterns for OO design, with names such as Strategy and Adapter. These 23 patterns, authored by four people, are therefore called the Gang of Four[6] (or GoF) design patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [4] 模式的概念起源于克里斯托弗·亚历山大 [AIS77] 的(建筑)建筑模式。软件模式起源于 1980 年代的 Kent Beck,他注意到了 Alexander 在体系结构中的模式工作,然后由 Beck 与泰克的 Ward Cunningham [BC87Beck94] 共同开发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [4] The notion of patterns originated with the (building) architectural patterns of Christopher Alexander [AIS77]. Patterns for software originated in the 1980s with Kent Beck, who became aware of Alexander's pattern work in architecture, and then were developed by Beck with Ward Cunningham [BC87, Beck94] at Tektronix.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [5]出版商将出版日期列为 1995 年,但它是在 1994 年 10 月发布的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [5] Publishers list the publication date as 1995, but it was released October 1994.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [6] 这也是一个与毛去世后 1970 年代中期中国政治有关的微妙笑话。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [6] Also a subtle joke related to mid-1970s Chinese politics following Mao's death.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  但是,Design Patterns 并不是一本介绍性的书;它假定您具备重要的 OO 设计和编程知识,并且大多数代码示例都是 C++ 语言。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  However, Design Patterns isn't an introductory book; it assumes significant prior OO design and programming knowledge, and most code examples are in C++.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  本书的后面的中间章节,特别是第 26 章(第 435 页)、第 35 章(第 579 页)和第 38 章(第 625 页)介绍了许多最常用的 GoF 设计模式,并将它们应用于我们的案例研究。另见第 ix 页的“按主要主题分类的内容”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Laterintermediatechapters of this book, especially Chapter 26 (p. 435), Chapter 35 (p. 579), and Chapter 38 (p. 625) introduce many of the most frequently used GoF design patterns and apply them to our case studies. Also: See "Contents by Major Topics" on page ix.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  学习 GRASP 和基本的 GoF 模式是本文的主要目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  It is a key goal of this text to learn both GRASP and essential GoF patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GRASP 是一组模式还是原则?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Is GRASP a Set of Patterns or Principles?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GRASP 定义了九个基本的 OO 设计原则或设计中的基本构建块。有些人问道,“GRASP 不是描述原则而不是模式吗?一个答案是 Gang of Four 作者的话,来自他们有影响力的 Design Patterns 书的序言:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GRASP defines nine basic OO design principles or basic building blocks in design. Some have asked, "Doesn't GRASP describe principles rather than patterns?" One answer is in the words of the Gang of Four authors, from the preface of their influential Design Patterns book:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  一个人的模式是另一个人的原始构建块。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  One person's pattern is another person's primitive building block.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  本文不关注标签,而是关注使用图案样式作为命名、呈现和记住基本经典设计思想的绝佳学习辅助工具的实用价值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Rather than focusing on labels, this text focuses on the pragmatic value of using the pattern style as an excellent learning aid for naming, presenting, and remembering basic, classic design ideas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    17.7. 我们现在在哪里?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    17.7. Where are We Now?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    到目前为止,本章总结了 OO 设计的背景:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    So far, this chapter has summarized the background for OO design:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. 迭代过程背景先验工件?它们与 OO 设计模型有何关系?我们应该花多少时间设计建模?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. The iterative process backgroundPrior artifacts? How do they relate to OO design models? How much time should we spend design modeling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    3. RDD 作为对象设计的隐喻一个由协作负责的对象组成的社区。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    4. RDD as a metaphor for object designa community of collaborating responsible objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    5. 模式作为命名和解释 OO 设计思想的一种方式,GRASP 用于分配职责的基本模式,GoF 用于更高级的设计思想。模式可以在建模和编码期间应用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    6. Patterns as a way to name and explain OO design ideasGRASP for basic patterns of assigning responsibilities, and GoF for more advanced design ideas. Patterns can be applied during modeling and during coding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    7. 用于 OO 设计可视化建模的 UML,在此期间可以应用 GRASP 和 GoF 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    8. UML for OO design visual modeling, during which time both GRASP and GoF patterns can be applied.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    了解了这一点后,是时候关注对象设计的一些细节了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With that understood, it's time to focus on some details of object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      17.8. 使用 GRASP 进行对象设计的简短示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      17.8. A Short Example of Object Design with GRASP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以下各节将更详细地探讨 GRASP,但让我们从一个较短的示例开始,看看应用于 Monopoly 案例研究的大创意。有九种 GRASP 模式;此示例应用以下子集:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Following sections explore GRASP in more detail, but let's start with a shorter example to see the big ideas, applied to the Monopoly case study. There are nine GRASP patterns; this example applies the following subset:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 造物主

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      所有 GRASP 模式都总结在本书的封面内侧。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      All the GRASP patterns are summarized on the inside front cover of this book.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      造物主

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:谁创建了 Square 对象?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 OO 设计中,您必须考虑的首要问题之一是:谁创建了对象 X?这是一种事的责任。例如,在 Monopoly 案例研究中,谁创建了一个 Square 软件对象?现在,任何对象都可以创建 Square,但许多 OO 开发人员会选择什么呢?为什么呢?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      One of the first problems you have to consider in OO design is: Who creates object X? This is a doing responsibility. For example, in the Monopoly case study, who creates a Square software object? Now, any object can create a Square, but what would many OO developers choose? And why?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Dog 对象(即某个任意类)成为创建者怎么样?不!我们可以在骨子里感觉到它。为什么?因为这是关键点,它并不符合我们对该领域的心智模型。Dog 不支持我们对域的看法与与软件对象的直接对应之间的低表示差距LRG)。我已经与成千上万的开发人员一起解决了这个问题,从印度到美国,几乎每个人都会说,“让 Board 对象创建正方形。有趣!它反映了一种“直觉”,即 OO 软件开发人员经常(稍后将探讨例外情况)希望“容器”创建“包含”的事物,例如创建正方形

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How about having a Dog object (i.e., some arbitrary class) be the creator? No! We can feel it in our bones. Why? Becauseand this is the critical pointit doesn't appeal to our mental model of the domain. Dog doesn't support low representational gap (LRG) between how we think of the domain and a straightforward correspondence with software objects. I've done this problem with literally thousands of developers, and virtually every one, from India to the USA, will say, "Make the Board object create the Squares." Interesting! It reflects an "intuition" that OO software developers often (exceptions are explored later) want "containers" to create the things "contained," such as Boards creating Squares.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      顺便说一句,为什么我们用 Square 和 Board 来定义软件类而不是 AB324ZC17 呢?答案:通过 LRG。这将 UP 领域模型与 UP 设计模型连接起来,或者将我们的领域心智模型连接到它在软件架构的领域层中的实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      By the way, why we are defining software classes with the names Square and Board, rather than the names AB324 and ZC17? Answer: By LRG. This connects the UP Domain Model to the UP Design Model, or our mental model of the domain to its realization in the domain layer of the software architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以此为背景,以下是 Creator 模式的定义[7]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      With that as background, here's the definition of the Creator pattern[7]:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [7] 其他创建模式,例如 Concrete FactoryAbstract Factory,将在后面讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [7] Alternate creation patterns, such as Concrete Factory and Abstract Factory, are discussed later.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      造物主

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      谁创建了 A?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Who creates an A?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(这可以被视为建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (this can be viewed as advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果满足以下条件之一,则分配类 B 创建类 A 实例的责任(越多越好):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Assign class B the responsibility to create an instance of class A if one of these is true (the more the better):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B “包含”或复合聚合 A。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B "contains" or compositely aggregates A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B 记录 A。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B records A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B 与 A 非常相似。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B closely uses A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B 具有 A 的初始化数据。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • B has the initializing data for A.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,这与责任分配有关。让我们看看如何应用 Creator。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Notice this has to do with responsibility assignment. Let's see how to apply Creator.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      首先,在应用 Creator 和其他 GRASP 模式时,一个微妙但重要的点:BA 指的是软件对象,而不是域模型对象。我们首先尝试通过查找满足 B 角色的现有软件对象来应用 Creator。但是,如果我们刚刚开始 OO 设计,并且我们还没有定义任何软件类呢?在这种情况下,LRG 从域模型中获得灵感。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      First, a subtle but important point in applying Creator and other GRASP patterns: B and A refer to software objects, not domain model objects. We first try to apply Creator by looking for existing software objects that satisfy the role of B. But what if we are just starting the OO design, and we have not yet defined any software classes? In this case, by LRG, look to the domain model for inspiration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因此,对于 Square 创建问题,由于尚未定义软件类,我们查看图 17.3 中的域模型,可以看到 Board 包含 Square。这是一个概念角度,而不是软件角度,但我们当然可以在 Design Model 中对其进行镜像,以便软件 Board 对象包含软件 Square 对象。然后根据 LRG 和创建者的建议,董事会将创建方格。此外,方块将永远是一个 Board 的一部分,而 Board 管理它们的创建和销毁;因此,他们与董事会处于复合聚合协会中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thus, for the Square creation problem, since no software classes are yet defined, we look at the domain model in Figure 17.3 and see that a Board contains Squares. That's a conceptual perspective, not a software one, but of course we can mirror it in the Design Model so that a software Board object contains software Square objects. And then consistent with LRG and the Creator advice, the Board will create Squares. Also, Squares will always be a part of one Board, and Board manages their creation and destruction; thus, they are in a composite aggregation association with the Board.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.3.垄断迭代 1 域模型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      回想一下,敏捷建模实践是创建并行互补的动态和静态对象模型。因此,我绘制了部分序列图和类图,以反映此设计决策,其中我在绘制 UML 图时应用了 GRASP 模式。参见图 17.4图 17.5。请注意,在图 17.4 中,当 Board 被创建时,它会创建一个 Square。为了在这个例子中简洁起见,我将忽略绘制循环以创建所有 40 个方格的附带问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Recall that an agile modeling practice is to create parallel complementary dynamic and static object models. Therefore, I've drawn both a partial sequence diagram and class diagram to reflect this design decision in which I've applied a GRASP pattern while drawing UML diagrams. See Figure 17.4 and Figure 17.5. Notice in Figure 17.4 that when the Board is created, it creates a Square. For brevity in this example, I'll ignore the side issue of drawing the loop to create all 40 squares.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.4.在动态模型中应用 Creator 模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.5.在设计模型的 DCD 中,BoardSquares 具有复合聚合关联。我们在静态模型中应用 Creator。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:给定键,谁知道 Square 对象是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      模式 Information Expert(通常缩写为 Expert)是对象设计中最基本的职责分配原则之一。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The pattern Information Expert (often abbreviated to Expert) is one of the most basic responsibility assignment principles in object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      假设对象需要能够引用给定其名称的特定 Square。谁应该负责了解给定密钥的 Square?当然,这是一种知情的责任,但 Expert 也适用于实践

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Suppose objects need to be able to reference a particular Square, given its name. Who should be responsible for knowing a Square, given a key? Of course, this is a knowing responsibility, but Expert also applies to doing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      与 Creator 一样,任何对象都可以负责,但许多 OO 开发人员会选择什么呢?为什么呢?与 Creator 问题一样,大多数 OO 开发人员选择 Board 对象。将这一责任分配给董事会似乎是显而易见的,但解构原因并学会在更微妙的情况下应用这一原则是有启发性的。后面的例子会变得更加微妙。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As with Creator, any object can be responsible, but what would many OO developers choose? And why? As with the Creator problem, most OO developers choose the Board object. It seems sort of trivially obvious to assign this responsibility to a Board, but it is instructive to deconstruct why, and to learn to apply this principle in more subtle cases. Later examples will get more subtle.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      信息专家解释了选择董事会的原因:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Information Expert explains why the Board is chosen:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为对象分配责任的基本原则是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What is a basic principle by which to assign responsibilities to objects?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      将责任分配给具有完成该责任所需信息的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Assign a responsibility to the class that has the information needed to fulfill it.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      责任需要有关其他对象的信息、对象自身的状态、对象周围的世界、对象可以派生的信息,等等。在这种情况下,为了能够检索和呈现任何一个给定其命名的 Square,某个对象必须知道(拥有信息)所有 Square。我们之前决定,如图 17.5 所示,软件将聚合所有 Square 对象。因此,董事会拥有履行此责任所需的信息。图 17.6 说明了在绘图上下文中应用 Expert。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A responsibility needs information for its fulfillmentinformation about other objects, an object's own state, the world around an object, information the object can derive, and so forth. In this case, to be able to retrieve and present any one Squaregiven its namesome object must know (have the information) about all the Squares. We previously decided, as shown in Figure 17.5, that a software Board will aggregate all the Square objects. Therefore, Board has the information necessary to fulfill this responsibility. Figure 17.6 illustrates applying Expert in the context of drawing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.6.应用专家。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      下一个 GRASP 原则 Low Coupling 解释了为什么 Expert 是 OO 设计的有用核心原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The next GRASP principle, Low Coupling, explains why Expert is a useful, core principle of OO design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:为什么 Board 而不是 Dog?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      专家 指导我们将了解特定方格的责任分配给 Board 对象,因为 Board 知道所有方格(它有信息它是信息专家)。但为什么 Expert 会给出这个建议呢?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Expert guides us to assign the responsibility to know a particular Square, given a unique name, to the Board object because the Board knows about all the Squares (it has the informationit is the Information Expert). But why does Expert give this advice?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      答案在于低耦合原理。简单来说,耦合是衡量一个元素与其他元素相连、了解或依赖于其他元素的强度的指标。如果存在耦合或依赖关系,则当被依赖的元素发生变化时,依赖元素可能会受到影响。例如,子类与超类强耦合。调用对象 B 操作的对象 AB 的服务耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The answer is found in the principle of Low Coupling. Briefly and informally, coupling is a measure of how strongly one element is connected to, has knowledge of, or depends on other elements. If there is coupling or dependency, then when the depended-upon element changes, the dependant may be affected. For example, a subclass is strongly coupled to a superclass. An object A that calls on the operations of object B has coupling to B's services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      低耦合原则适用于软件开发的许多方面;这确实是构建软件的主要目标之一。在对象设计和职责方面,我们可以将建议描述如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Low Coupling principle applies to many dimensions of software development; it's really one of the cardinal goals in building software. In terms of object design and responsibilities, we can describe the advice as follows:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如何减少变更的影响?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How to reduce the impact of change?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      分配职责,使 (不必要的) 耦合保持较低水平。使用此原则来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Assign responsibilities so that (unnecessary) coupling remains low. Use this principle to evaluate alternatives.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      我们使用低耦合来评估现有设计或评估新备选方案之间的选择,在其他条件相同的情况下,我们应该首选耦合度低于备选方案的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      We use Low Coupling to evaluate existing designs or to evaluate the choice between new alternativesall other things being equal, we should prefer a design whose coupling is lower than the alternatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,正如我们在图 17.5 中决定的那样,一个 Board 对象包含许多 Square。为什么不将 getSquare 分配给 Dog(即任意的其他类)?考虑低耦合的影响。如果一个 DoggetSquare,如图 17.7 中的 UML 草图所示,它必须与 Board 协作才能获得 Board 中所有 Square 的集合。它们可能存储在 Map 集合对象中,该对象允许通过键进行检索。然后,Dog 可以通过键访问并返回一个特定的 Square

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, as we've decided in Figure 17.5, a Board object contains many Squares. Why not assign getSquare to Dog (i.e., some arbitrary other class)? Consider the impact in terms of low coupling. If a Dog has getSquare, as shown in the UML sketch in Figure 17.7, it must collaborate with the Board to get the collection of all the Squares in the Board. They are probably stored in a Map collection object, which allows retrieval by a key. Then, the Dog can access and return one particular Square by the key name.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.7.评估耦合对该设计的影响。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      但是,让我们评估一下这个糟糕的 Dog 设计与我们的原始设计(Board 执行 getSquare)的总耦合。在 Dog 的情况下,DogBoard 都必须知道 Square 对象(两个对象与 Square 耦合);在 Board 的情况下,只有 Board 必须知道 Square 对象(一个对象与 Square 耦合)。因此,Board 设计的整体耦合较低,并且在所有其他条件相同的情况下,在支持低耦合目标方面,它优于 Dog 设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      But let's evaluate the total coupling with this poor Dog design versus our original design where Board does getSquare. In the Dog case, the Dog and the Board must both know about Square objects (two objects have coupling to Square); in the Board case, only Board must know about Square objects (one object has coupling to Square). Thus, the overall coupling is lower with the Board design, and all other things being equal, it is better than the Dog design, in terms of supporting the goal of Low Coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在更高的目标级别上,为什么需要低耦合?换句话说,我们为什么要减少变更的影响?因为 Low Coupling 往往会减少修改软件的时间、精力和缺陷。这是一个简短的回答,但对构建和维护软件具有重大影响!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      At a higher-goal level, why is Low Coupling desirable? In other words, why would we want to reduce the impact of change? Because Low Coupling tends to reduce the time, effort, and defects in modifying software. That's a short answer, but one with big implications in building and maintaining software!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      关键点: 专家支持低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Key Point: Expert Supports Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      回到 Information Expert 的动机:它指导我们选择支持 Low Coupling。Expert 要求我们找到具有职责所需大部分信息的对象(例如,Board)并在其中分配职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To return to the motivation for Information Expert: it guides us to a choice that supports Low Coupling. Expert asks us to find the object that has most of the information required for the responsibility (e.g., Board) and assign responsibility there.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果我们把责任放在其他任何地方(例如,Dog),整体耦合会更高,因为更多的信息或对象必须在它们的原始来源或家之外共享,因为 Map 集合中的方块必须与 Dog 共享,远离它们在 Board 中的家。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If we put the responsibility anywhere else (e.g., Dog), the overall coupling will be higher because more information or objects must be shared away from their original source or home, as the squares in the Map collection had to be shared with the Dog, away from their home in the Board.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      应用 UML: 请注意图 17.7 中序列图中的一些 UML 元素:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Applying UML: Please note a few UML elements in the sequence diagram in Figure 17.7:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • getAllSquares 消息中的返回值变量 sqs 也用于以 sqs 命名生命线对象:Map<Square>(例如,包含 Square 对象的 Map 类型的集合)。在生命线框中引用返回值变量(以向其发送消息)是很常见的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The return value variable sqs from the getAllSquares message is also used to name the lifeline object in sqs : Map<Square> (e.g., a collection of type Map that holds Square objects). Referencing a return value variable in a lifeline box (to send it messages) is common.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 起始 getSquare 消息中的变量 s 和后面的 get 消息中的变量 s 引用同一个对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The variable s in the starting getSquare message and the variable s in the later get message refer to the same object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 消息表达式 s = get(name) : Square 表示 s 的类型是对 Square 实例的引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The message expression s = get(name) : Square indicates that the type of s is a reference to a Square instance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      简单的分层体系结构具有 UI 层和域层等。参与者(如 Monopoly 游戏中的人类观察者)会生成 UI 事件,例如使用鼠标单击按钮来玩游戏。然后,UI 软件对象(例如,在 Java 中为 JFrame 窗口和 JButton 按钮)必须对鼠标单击事件做出反应,并最终导致游戏开始运行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A simple layered architecture has a UI layer and a domain layer, among others. Actors, such as the human observer in the Monopoly game, generate UI events, such as clicking on a button with a mouse to play the game. The UI software objects (in Java for example, a JFrame window and a JButton button) must then react to the mouse click event and ultimately cause the game to play.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      根据模型-视图分离原则,我们知道 UI 对象不应包含应用程序或 “业务” 逻辑,例如计算玩家的移动。因此,一旦 UI 对象拾取了鼠标事件,它们就需要将请求委托(将任务转发给另一个对象)到域层中的域对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      From the Model-View Separation Principle, we know the UI objects should not contain application or "business" logic such as calculating a player's move. Therefore, once the UI objects pick up the mouse event, they need to delegate (forward the task to another object) the request to domain objects in the domain layer.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Controller 模式回答了这个简单的问题:UI 层之后或之后的第一个对象应该从 UI 层接收消息?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Controller pattern answers this simple question: What first object after or beyond the UI layer should receive the message from the UI layer?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为了将其与系统序列图联系起来,正如对图 17.8 的回顾所示,关键的系统操作是 playGame。不知何故,人类观察者生成了一个 playGame 请求(可能是通过单击标有“Play Game”的 GUI 按钮),然后系统做出响应。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To tie this back to system sequence diagrams, as a review of Figure 17.8 shows, the key system operation is playGame. Somehow the human observer generates a playGame request (probably by clicking on a GUI button labeled "Play Game") and the system responds.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.8.用于大富翁游戏的 SSD。请注意 playGame 操作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.9 说明了更细粒度的情况,假设有一个 Java Swing GUI JFrame 窗口和 JButton 按钮。[8] 单击JButton会向某个对象发送actionPerformed消息,通常是JFrame窗口本身,如图 17.9 所示。然后,这是 JFrame 窗口必须将 actionPerformed 消息改编为语义上更有意义的内容,例如 playGame 消息(对应于 SSD 分析),并将 playGame 消息委托给域层中的域对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 17.9 illustrates a finer-grained look at what's going on, assuming a Java Swing GUI JFrame window and JButton button.[8] Clicking on a JButton sends an actionPerformed message to some object, often to the JFrame window itself, as we see in Figure 17.9. Thenand this is the key pointthe JFrame window must adapt that actionPerformed message into something more semantically meaningful, such as a playGame message (to correspond to the SSD analysis), and delegate the playGame message to a domain object in the domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [8] 类似的对象、消息和协作模式适用于 .NET、Python 等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [8] Similar objects, messages, and collaboration patterns apply to .NET, Python, etc.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.9.谁是 playGame 系统操作的 Controller?



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      您是否看到 SSD 系统操作与从 UI 到域层的详细对象设计之间的联系?这很重要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Do you see the connection between the SSD system operations and the detailed object design from the UI to domain layer? This is important.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因此,Controller 处理了 OO 设计中的一个基本问题:如何将 UI 层连接到应用程序逻辑层?Board 是否应该成为第一个从 UI 层接收 playGame 消息的对象?还是其他东西?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thus, Controller deals with a basic question in OO design: How to connect the UI layer to the application logic layer? Should the Board be the first object to receive the playGame message from the UI layer? Or something else?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在某些 OOA/D 方法中,名称 controller 被赋予接收和“控制”(协调)处理请求的应用程序逻辑对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In some OOA/D methods, the name controller was given to the application logic object that received and "controlled" (coordinated) handling the request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Controller 模式提供了以下建议:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Controller pattern offers the following advice:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UI 层之外的第一个对象接收和协调 (“控件”) 系统操作?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What first object beyond the UI layer receives and coordinates ("controls") a system operation?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      将责任分配给表示以下选项之一的对象:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Assign the responsibility to an object representing one of these choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 表示整个 “系统”、“根对象”、运行软件的设备或主要子系统(这些都是 Facade 控制器的变体)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Represents the overall "system," a "root object," a device that the software is running within, or a major subsystem (these are all variations of a facade controller).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 表示系统操作发生的用例场景(用例或会话控制器)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Represents a use case scenario within which the system operation occurs (a use case or session controller)



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      让我们考虑这些选项:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Let's consider these options:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      选项 1: 表示整个“系统”或“根对象”,例如名为 MonopolyGame 的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Option 1: Represents the overall "system," or a "root object"such as an object called MonopolyGame.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      选项 1: 表示在其中运行软件的设备此选项适用于专用硬件设备,例如电话或银行提款机(例如,软件类 PhoneBankCashMachine);它不适用于这种情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Option 1: Represents a device that the software is running withinthis option appertains to specialized hardware devices such as a phone or a bank cash machine (e.g., software class Phone or BankCashMachine); it doesn't apply in this case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      选项 2: 表示用例或会话。发生 playGame 系统操作的用例称为 Play Monopoly Game。因此,诸如 PlayMonopolyGameHandler 之类的软件类(附加“...Handler“或”...Session“是 OO 设计中的一个惯用语,当使用这个版本时)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Option 2: Represents the use case or session. The use case that the playGame system operation occurs within is called Play Monopoly Game. Thus, a software class such as PlayMonopolyGameHandler (appending "…Handler" or "…Session" is an idiom in OO design when this version is used).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果只有几个系统操作,选项 #1,类 MonopolyGame,是合理的(当我们讨论 High Cohesion 时,会有更多关于权衡的信息)。因此,图 17.10 说明了基于 Controller 的设计决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Option #1, class MonopolyGame, is reasonable if there are only a few system operations (more on the trade-offs when we discuss High Cohesion). Therefore, Figure 17.10 illustrates the design decision based on Controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.10.使用 MonopolyGame 应用控制器模式。将 UI 层连接到软件对象的域层。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      根据 Controller 的决策,我们现在位于右侧序列图所示的设计点。下一章将探讨对下一步如何一致且有条不紊地应用 GRASP 的详细设计讨论,但现在我们有两种截然不同的设计方法值得考虑,如图 17.11 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Based on the Controller decision, we are now at the design point shown in the sequence diagram to the right. The detailed design discussion of what comes nextconsistently and methodically applying GRASPis explored in a following chapter, but right now we have two contrasting design approaches worth considering, illustrated in Figure 17.11.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.11.对比不同设计的内聚水平。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,在左侧版本中,MonopolyGame 对象本身会执行所有工作,而在右侧版本中,它会委托和协调 playGame 请求的工作。在软件设计中,一种称为内聚的基本品质非正式地衡量软件元素的操作在功能上的关联程度,也衡量软件元素正在做多少工作。举个简单的对比示例,具有 100 个方法和 2,000 行源代码行的 Big 对象 (SLOC) 比具有 10 个方法和 200 行源代码行的 Small 对象要多得多。如果 Big 的 100 种方法涵盖了许多不同的职责领域(例如数据库访问随机数生成),那么 Big 的重点或功能内聚性低于 Small。总之,代码量和代码的相关性都是对象内聚的指标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Notice in the left-hand version that the MonopolyGame object itself does all the work, and in the right-hand version it delegates and coordinates the work for the playGame request. In software design a basic quality known as cohesion informally measures how functionally related the operations of a software element are, and also measures how much work a software element is doing. As a simple contrasting example, an object Big with 100 methods and 2,000 source lines of code (SLOC) is doing a lot more than an object Small with 10 methods and 200 source lines. And if the 100 methods of Big are covering many different areas of responsibility (such as database access and random number generation), then Big has less focus or functional cohesion than Small. In summary, both the amount of code and the relatedness of the code are an indicator of an object's cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      需要明确的是,不良内聚力(低内聚力)不仅仅意味着一个对象只能自己工作;事实上,具有 2,000 SLOC 的低内聚对象可能与许多其他对象协作。现在,这里有一个关键点:所有这些交互往往也会产生不良的 (高) 耦合。不良的内聚力和不良的耦合往往是齐头并进的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To be clear, bad cohesion (low cohesion) doesn't just imply an object does work only by itself; indeed, a low cohesion object with 2,000 SLOC probably collaborates with many other objects. Now, here's a key point: All that interaction tends to also create bad (high) coupling. Bad cohesion and bad coupling often go hand-in-hand.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 17.11 中的对比设计而言,左手版本的 MonopolyGame 的内聚力比右手版本差,因为左手版本让 MonopolyGame 对象自己完成所有工作,而不是在对象之间委派和分配工作。这导致了高内聚原则,该原则用于评估不同的设计选择。在所有其他条件相同的情况下,更喜欢具有更高内聚力的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In terms of the contrasting designs in Figure 17.11, the left-hand version of MonopolyGame has worse cohesion than the right-hand version, since the left-hand version is making the MonopolyGame object itself do all the work, rather than delegating and distributing work among objects. This leads to the principle of High Cohesion, which is used to evaluate different design choices. All other things being equal, prefer a design with higher cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如何保持对象的焦点、可理解性和可管理性,并作为副作用支持 Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How to keep objects focused, understandable, and manageable, and as a side effect, support Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      分配责任,以保持高度凝聚力。使用它来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Assign responsibilities so that cohesion remains high. Use this to evaluate alternatives.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                      可以说,右侧设计比左侧设计更能支持 High Cohesion。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      We can say that the right-hand design better supports High Cohesion than the left-hand version.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        17.9. 将 GRASP 应用于对象设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        17.9. Applying GRASP to Object Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        GRASP 代表 General Responsibility Assignment Software Patterns。[9]选择这个名字是为了暗示掌握这些原则对于成功设计面向对象软件的重要性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        GRASP stands for General Responsibility Assignment Software Patterns.[9] The name was chosen to suggest the importance of grasping these principles to successfully design object-oriented software.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [9] 从技术上讲,应该写 “GRAS Patterns” 而不是 “GRASP Patterns”,但后者听起来更好。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [9] Technically, one should write "GRAS Patterns" rather than "GRASP Patterns," but the latter sounds better.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本书的封面内页总结了所有九种 GRASP 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        All nine GRASP patterns are summarized on the inside front cover of this book.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                        理解并能够应用 GRASP 背后的思想在编码或绘制交互和类图时,使不熟悉对象技术的开发人员能够尽快掌握这些基本原理;它们构成了设计 OO 系统的基础。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Understanding and being able to apply the ideas behind GRASPwhile coding or while drawing interaction and class diagramsenables developers new to object technology needs to master these basic principles as quickly as possible; they form a foundation for designing OO systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有九种 GRASP 模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There are nine GRASP patterns:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        造物主

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        纯制造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Pure Fabrication

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        间接

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Indirection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Polymorphism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Protected Variations



                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本章的其余部分将更详细地重新研究前五个;其余四个在第 25 章中介绍,从第 413 页开始。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The remainder of this chapter reexamines the first five in more detail; the remaining four are introduced in Chapter 25 starting on p. 413.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          17.10. 创建者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          17.10. Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          谁应该负责创建某个类的新实例?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who should be responsible for creating a new instance of some class?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          对象创建是面向对象的系统中最常见的活动之一。因此,为分配创造责任制定一个一般原则是有用的。如果分配得当,该设计可以支持低耦合、更高的清晰度、封装和可重用性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The creation of objects is one of the most common activities in an object-oriented system. Consequently, it is useful to have a general principle for the assignment of creation responsibilities. Assigned well, the design can support low coupling, increased clarity, encapsulation, and reusability.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果其中之一为 true,则分配类 B 创建类 A 实例的责任(越多越好):[10]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign class B the responsibility to create an instance of class A if one of these is true (the more the better):[10]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [10]其他创建模式,如 Concrete FactoryAbstract Factory,将在后面探讨。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [10] Other creation patterns, such as Concrete Factory and Abstract Factory, are explored later.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B “包含”或复合聚合 A。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B "contains" or compositely aggregates A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B 记录 A。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B records A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B 与 A 非常相似。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B closely uses A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B 具有 A 的初始化数据,该数据将在创建 A 时传递给 A。因此,B 是创建 A 的专家。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • B has the initializing data for A that will be passed to A when it is created. Thus B is an Expert with respect to creating A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          B 是 A 对象的创建者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          B is a creator of A objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果有多个选项适用,通常首选聚合包含 A 类的 B 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If more than one option applies, usually prefer a class B which aggregates or contains class A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在 NextGen POS 应用程序中,谁应该负责创建 SalesLineItem 实例?对于 Creator,我们应该寻找一个聚合、包含等 SalesLineItem 实例的类。考虑图 17.12 中的部分域模型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the NextGen POS application, who should be responsible for creating a SalesLineItem instance? By Creator, we should look for a class that aggregates, contains, and so on, SalesLineItem instances. Consider the partial domain model in Figure 17.12.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 17.12.部分域模型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                          由于 Sale 包含(实际上聚合了)许多 SalesLineItem 对象,因此 Creator 模式表明 Sale 是负责创建 SalesLineItem 实例的不错选择。这导致了 Object 交互的设计,如图 17.13 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Since a Sale contains (in fact, aggregates) many SalesLineItem objects, the Creator pattern suggests that Sale is a good candidate to have the responsibility of creating SalesLineItem instances. This leads to the design of object interactions shown in Figure 17.13.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 17.13.创建 SalesLineItem。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这种职责分配要求在 Sale 中定义 makeLineItem 方法。再一次,我们考虑和决定这些职责的背景是在绘制交互图时。然后,类图的 method 部分可以总结责任分配结果,具体实现为方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This assignment of responsibilities requires that a makeLineItem method be defined in Sale. Once again, the context in which we considered and decided on these responsibilities was while drawing an interaction diagram. The method section of a class diagram can then summarize the responsibility assignment results, concretely realized as methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Creator 指导分配与对象创建相关的职责,这是一项非常常见的任务。Creator 模式的基本目的是找到一个在任何情况下都需要连接到所创建对象的 creator。选择它作为 creator 支持低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Creator guides the assigning of responsibilities related to the creation of objects, a very common task. The basic intent of the Creator pattern is to find a creator that needs to be connected to the created object in any event. Choosing it as the creator supports low coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          复合聚合 Part、Container contains Content 和 Recorder 记录。记录是类图中类之间非常常见的关系。Creator 建议封闭的容器或记录器类是负责创建包含或记录的事物的良好候选者。当然,这只是一个指导方针。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Composite aggregates Part, Container contains Content, and Recorder records. Recorded are all very common relationships between classes in a class diagram. Creator suggests that the enclosing container or recorder class is a good candidate for the responsibility of creating the thing contained or recorded. Of course, this is only a guideline.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,在考虑 Creator 模式时,我们转向了组合的概念。复合对象是制作其零件的绝佳候选对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that we turned to the concept of composition in considering the Creator pattern. A composite object is an excellent candidate to make its parts.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有时,您可以通过查找具有将在创建期间传入的初始化数据的类来识别创建者。这实际上是 Expert 模式的一个示例。初始化数据是在创建过程中通过某种初始化方法(例如具有参数的 Java 构造函数)传入的。例如,假设 Payment 实例在创建时需要使用 Sale 总额进行初始化。由于 Sale 知道总数,因此 SalePayment 的候选创建者。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Sometimes you identify a creator by looking for the class that has the initializing data that will be passed in during creation. This is actually an example of the Expert pattern. Initializing data is passed in during creation via some kind of initialization method, such as a Java constructor that has parameters. For example, assume that a Payment instance, when created, needs to be initialized with the Sale total. Since Sale knows the total, Sale is a candidate creator of the Payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          通常,创建需要非常复杂,例如使用回收的实例来提高性能,根据某些外部属性值有条件地从一系列类似类之一创建实例,等等。在这些情况下,建议将创建委托给称为 Concrete FactoryAbstract Factory [GHJV95] 的帮助程序类,而不是使用 Creator 建议的类。从第 440 页开始讨论工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Often, creation requires significant complexity, such as using recycled instances for performance, conditionally creating an instance from one of a family of similar classes based upon some external property value, and so forth. In these cases, it is advisable to delegate creation to a helper class called a Concrete Factory or an Abstract Factory [GHJV95] rather than use the class suggested by Creator. Factories are discussed starting on p. 440.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 支持低耦合,这意味着更低的维护依赖性和更高的重用机会。耦合可能不会增加,因为创建的类可能已经对 creator 类可见,因为现有的关联促使它选择作为 creator。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Low coupling is supported, which implies lower maintenance dependencies and higher opportunities for reuse. Coupling is probably not increased because the created class is likely already visible to the creator class, due to the existing associations that motivated its choice as creator.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          相关模式或原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Related Patterns or Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 混凝土工厂和抽象工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Concrete Factory and Abstract Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Whole-Part [BMRSS96] 描述了一种模式,用于定义支持组件封装的聚合对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Whole-Part [BMRSS96] describes a pattern to define aggregate objects that support encapsulation of components.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            17.11. 信息专家(或专家)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            17.11. Information Expert (or Expert)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            为对象分配责任的一般原则是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What is a general principle of assigning responsibilities to objects?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            设计模型可以定义成百上千个软件类,而应用程序可能需要成百上千个责任才能完成。在对象设计期间,当定义对象之间的交互时,我们会选择将职责分配给软件类。如果我们选择得当,系统往往更容易理解、维护和扩展,并且我们的选择提供了更多机会在未来的应用程序中重用组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A Design Model may define hundreds or thousands of software classes, and an application may require hundreds or thousands of responsibilities to be fulfilled. During object design, when the interactions between objects are defined, we make choices about the assignment of responsibilities to software classes. If we've chosen well, systems tend to be easier to understand, maintain, and extend, and our choices afford more opportunity to reuse components in future applications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            将责任分配给信息专家具有履行职责所需信息的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Assign a responsibility to the information expertthe class that has the information necessary to fulfill the responsibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在 NextGEN POS 应用程序中,某些类需要知道销售总额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the NextGEN POS application, some class needs to know the grand total of a sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            通过明确说明责任来开始分配职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Start assigning responsibilities by clearly stating the responsibility.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            根据这个建议,陈述是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            By this advice, the statement is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            谁应该负责了解销售的总金额?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Who should be responsible for knowing the grand total of a sale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            通过 Information Expert,我们应该寻找具有确定总数所需信息的对象类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            By Information Expert, we should look for that class of objects that has the information needed to determine the total.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            现在我们来到一个关键问题:我们是查看 Domain Model 还是 Design Model 来分析具有所需信息的类?域模型说明了实际域的概念类;设计模型说明了软件类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Now we come to a key question: Do we look in the Domain Model or the Design Model to analyze the classes that have the information needed? The Domain Model illustrates conceptual classes of the real-world domain; the Design Model illustrates software classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            答:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Answer:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. 如果 Design Model 中有相关的类,请先查看该类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2. If there are relevant classes in the Design Model, look there first.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            3. 否则,请查看 Domain Model,并尝试使用 (或扩展) 其表示形式来激发创建相应设计类的灵感。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            4. Otherwise, look in the Domain Model, and attempt to use (or expand) its representations to inspire the creation of corresponding design classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,假设我们刚刚开始设计工作,并且没有或只有最小的 Design Model。因此,我们向 Domain Model 寻求信息专家;也许现实世界的 Sale 就是其中之一。然后,我们将一个类似名称为 Sale 的软件类添加到设计模型中,并赋予它了解其总数的责任,用名为 getTotal 的方法表示。这种方法支持低表示差距,其中对象的软件设计吸引了我们关于真实域如何组织的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, assume we are just starting design work and there is no, or a minimal, Design Model. Therefore, we look to the Domain Model for information experts; perhaps the real-world Sale is one. Then, we add a software class to the Design Model similarly called Sale, and give it the responsibility of knowing its total, expressed with the method named getTotal. This approach supports low representational gap in which the software design of objects appeals to our concepts of how the real domain is organized.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            要详细检查这种情况,请考虑图 17.14 中的部分域模型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To examine this case in detail, consider the partial Domain Model in Figure 17.14.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 17.14.销售协会。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            我们需要哪些信息来确定总计?我们需要了解销售的所有 SalesLineItem 实例及其小计之和。Sale 实例包含这些内容;因此,根据 Information Expert 的指导方针,Sale 是适合承担此职责的对象类别;它是这项工作的信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What information do we need to determine the grand total? We need to know about all the SalesLineItem instances of a sale and the sum of their subtotals. A Sale instance contains these; therefore, by the guideline of Information Expert, Sale is a suitable class of object for this responsibility; it is an information expert for the work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如前所述,正是在创建交互图的背景下,这些责任问题经常出现。想象一下,我们开始绘制图表,以便为对象分配责任。图 17.15 中的部分交互图和类图说明了一些决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            As mentioned, it is in the context of the creation of interaction diagrams that these questions of responsibility often arise. Imagine we are starting to work through the drawing of diagrams in order to assign responsibilities to objects. A partial interaction diagram and class diagram in Figure 17.15 illustrate some decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 17.15.部分交互和类图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            我们还没有完成。我们需要哪些信息来确定订单项小计?SalesLineItem.quantityProductDescription.priceSalesLineItem 知道其数量及其关联的 ProductDescription;因此,根据 Expert,SalesLineItem 应确定小计;它是信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We are not done yet. What information do we need to determine the line item subtotal? SalesLineItem.quantity and ProductDescription.price. The SalesLineItem knows its quantity and its associated ProductDescription; therefore, by Expert, SalesLineItem should determine the subtotal; it is the information expert.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            就交互图而言,这意味着 Sale 应该向每个 SalesLineItems 发送 getSubtotal 消息并对结果求和;这个设计如图 17.16 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In terms of an interaction diagram, this means that the Sale should send getSubtotal messages to each of the SalesLineItems and sum the results; this design is shown in Figure 17.16.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 17.16.计算 Sale total。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            为了履行了解和回答其小计的责任,SalesLineItem 必须知道产品价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To fulfill the responsibility of knowing and answering its subtotal, a SalesLineItem has to know the product price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ProductDescription 是回答其价格的信息专家;因此,SalesLineItem 会向其发送一条消息,询问产品价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The ProductDescription is an information expert on answering its price; therefore, SalesLineItem sends it a message asking for the product price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            该设计如图 17.17 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The design is shown in Figure 17.17.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 17.17.计算 Sale total。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            总之,为了履行了解和回答销售总额的责任,我们为三个设计类别的对象分配了三项责任,如下所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In conclusion, to fulfill the responsibility of knowing and answering the sale's total, we assigned three responsibilities to three design classes of objects as follows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            设计类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Design Class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            责任

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Responsibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            了解销售总额

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            knows sale total

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SalesLineItem 销售行项目

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            知道行项目小计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            knows line item subtotal

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            产品描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            了解产品价格

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            knows product price



                                                                                                                                                                                                                                                                                                                                                                                                                                                                            我们在绘制交互图的上下文中考虑并决定了这些责任。然后,我们可以在类图的 method 部分中总结这些方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We considered and decided on these responsibilities in the context of drawing an interaction diagram. We could then summarize the methods in the method section of a class diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            我们分配每项职责的原则是 Information Expert将其与具有完成它所需信息的对象放在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The principle by which we assigned each responsibility was Information Expertplacing it with the object that had the information needed to fulfill it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Information Expert 经常用于职责分配;它是对象设计中持续使用的基本指导原则。Expert 并不意味着是一个晦涩或花哨的想法;它表达了一种常见的 “直觉”,即对象会做与它们所拥有的信息相关的事情。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Information Expert is frequently used in the assignment of responsibilities; it is a basic guiding principle used continuously in object design. Expert is not meant to be an obscure or fancy idea; it expresses the common "intuition" that objects do things related to the information they have.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            请注意,履行职责通常需要分布在不同对象类中的信息。这意味着许多 “部分” 信息专家将协作完成任务。例如,销售总额问题最终需要三类对象的协作。每当信息分布在不同的对象上时,它们都需要通过消息进行交互以共享工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Notice that the fulfillment of a responsibility often requires information that is spread across different classes of objects. This implies that many "partial" information experts will collaborate in the task. For example, the sales total problem ultimately required the collaboration of three classes of objects. Whenever information is spread across different objects, they will need to interact via messages to share the work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            专家通常会导致软件对象执行通常对它所代表的无生命的现实世界事物执行的操作的设计;Peter Coad 称之为 “Do It Myself” 策略 [Coad95]。例如,在现实世界中,如果不使用机电辅助工具,销售并不会告诉您其总数;它是一个无生命的东西。有人计算销售总额。但在面向对象的软件领域,所有软件对象都是“活的”或“动画的”,它们可以承担责任和做事。从根本上说,他们做的事与他们知道的信息有关。我将此称为对象设计中的“动画”原则;这就像在卡通片中,一切都是活生生的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Expert usually leads to designs where a software object does those operations that are normally done to the inanimate real-world thing it represents; Peter Coad calls this the "Do It Myself" strategy [Coad95]. For example, in the real world, without the use of electro-mechanical aids, a sale does not tell you its total; it is an inanimate thing. Someone calculates the total of the sale. But in object-oriented software land, all software objects are "alive" or "animated," and they can take on responsibilities and do things. Fundamentally, they do things related to the information they know. I call this the "animation" principle in object design; it is like being in a cartoon where everything is alive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            与对象技术中的许多事物一样,信息专家模式有一个现实世界的类比。我们通常将责任交给拥有完成任务所需信息的个人。例如,在企业中,谁应该负责创建损益表?有权访问创建它所需的所有信息的人也许是首席财务官。正如软件对象之所以协作,是因为信息四处传播,人也是如此。公司的首席财务官可能会要求会计师生成贷方和借方报告。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Information Expert patternlike many things in object technologyhas a real-world analogy. We commonly give responsibility to individuals who have the information necessary to fulfill a task. For example, in a business, who should be responsible for creating a profit-and-loss statement? The person who has access to all the information necessary to create itperhaps the chief financial officer. And just as software objects collaborate because the information is spread around, so it is with people. The company's chief financial officer may ask accountants to generate reports on credits and debits.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在某些情况下,Expert 建议的解决方案是不可取的,通常是因为耦合和内聚方面的问题(这些原则将在本章后面讨论)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In some situations, a solution suggested by Expert is undesirable, usually because of problems in coupling and cohesion (these principles are discussed later in this chapter).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,谁应该负责将 Sale 保存在数据库中?当然,要保存的大部分信息都在 Sale 对象中,因此 Expert 可以争辩说责任在于 Sale 类。而且,通过此决策的逻辑扩展,每个类都将有自己的服务以将自身保存在数据库中。但是根据这种推理采取行动会导致内聚、耦合和重复方面的问题。例如,Sale 类现在必须包含与数据库处理相关的逻辑,例如与 SQL 和 JDBC(Java 数据库连接)相关的逻辑。该类不再只关注 “being a sale” 的纯粹应用程序逻辑。现在,其他类型的责任降低了它的凝聚力。该类必须与另一个子系统的技术数据库服务(比如 JDBC 服务)耦合,而不仅仅是耦合到软件对象的域层中的其他对象,因此它的耦合会增加。并且类似的数据库逻辑很可能在许多持久类中重复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, who should be responsible for saving a Sale in a database? Certainly, much of the information to be saved is in the Sale object, and thus Expert could argue that the responsibility lies in the Sale class. And, by logical extension of this decision, each class would have its own services to save itself in a database. But acting on that reasoning leads to problems in cohesion, coupling, and duplication. For example, the Sale class must now contain logic related to database handling, such as that related to SQL and JDBC (Java Database Connectivity). The class no longer focuses on just the pure application logic of "being a sale." Now other kinds of responsibilities lower its cohesion. The class must be coupled to the technical database services of another subsystem, such as JDBC services, rather than just being coupled to other objects in the domain layer of software objects, so its coupling increases. And it is likely that similar database logic would be duplicated in many persistent classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            所有这些问题都表明违反了一个基本的架构原则:为分离主要系统关注点而设计。将应用程序逻辑保存在一个位置(例如域软件对象),将数据库逻辑保存在另一个位置(例如单独的持久化服务子系统)等等,而不是将不同的系统关注点混合在同一个组件中。[11]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            All these problems indicate violation of a basic architectural principle: design for a separation of major system concerns. Keep application logic in one place (such as the domain software objects), keep database logic in another place (such as a separate persistence services subsystem), and so forth, rather than intermingling different system concerns in the same component.[11]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [11] 有关关注点分离的讨论,请参见第 33 章

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [11] See Chapter 33 for a discussion of separation of concerns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            支持主要关注点的分离可以提高设计中的耦合和内聚。因此,即使通过 Expert,我们可以找到一些理由将数据库服务的责任放在 Sale 类中,但由于其他原因(通常是内聚和耦合),我们最终会得到一个糟糕的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Supporting a separation of major concerns improves coupling and cohesion in a design. Thus, even though by Expert we could find some justification for putting the responsibility for database services in the Sale class, for other reasons (usually cohesion and coupling), we'd end up with a poor design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 由于对象使用自己的信息来完成任务,因此会维护信息封装。这通常支持低耦合,从而产生更健壮和可维护的系统。Low Coupling 也是一种 GRASP 模式,将在下一节中讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Information encapsulation is maintained since objects use their own information to fulfill tasks. This usually supports low coupling, which leads to more robust and maintainable systems. Low Coupling is also a GRASP pattern that is discussed in a following section.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 行为分布在具有所需信息的类中,从而鼓励使用更内聚的“轻量级”类定义,这些类定义更易于理解和维护。通常支持高内聚(稍后讨论另一种模式)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Behavior is distributed across the classes that have the required information, thus encouraging more cohesive "lightweight" class definitions that are easier to understand and maintain. High cohesion is usually supported (another pattern discussed later).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            相关模式或原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Related Patterns or Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            也称为;似

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Also Known As; Similar To

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            “用数据来承担责任”、“知道的,就做”、“自己动手”、“把服务放在它们所工作的属性上”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            "Place responsibilities with data," "That which knows, does," "Do It Myself," "Put Services with the Attributes They Work On."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              17.12. 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              17.12. Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如何支持低依赖性、低变更影响和更高的重用率?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How to support low dependency, low change impact, and increased reuse?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              耦合是衡量一个元素与其他元素相连、了解或依赖其他元素的强度的指标。低(或弱)耦合的单元不依赖于太多其他单元;“太多”取决于上下文,但我们还是会研究它。这些元素包括类、子系统、系统等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Coupling is a measure of how strongly one element is connected to, has knowledge of, or relies on other elements. An element with low (or weak) coupling is not dependent on too many other elements; "too many" is context dependent, but we examine it anyway. These elements include classes, subsystems, systems, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              具有高 (或强) 耦合的类依赖于许多其他类。这样的类可能是不可取的;有些人患有以下问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A class with high (or strong) coupling relies on many other classes. Such classes may be undesirable; some suffer from the following problems:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 由于相关类中的更改而强制进行本地更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Forced local changes because of changes in related classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 孤立地更难理解。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Harder to understand in isolation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 更难重用,因为它的使用需要它所依赖的类的额外存在。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Harder to reuse because its use requires the additional presence of the classes on which it is dependent.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分配责任,使耦合保持较低水平。使用此原则来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Assign a responsibility so that coupling remains low. Use this principle to evaluate alternatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              请考虑以下来自 NextGen 案例研究的分部类图:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Consider the following partial class diagram from a NextGen case study:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              假设我们需要创建一个 Payment 实例并将其与 Sale 关联。哪个类应该对此负责?由于 Register 在实际域中“记录”了 Payment,因此 Creator 模式建议 Register 作为创建 Payment 的候选项。然后,Register 实例可以向 Sale 发送 addPayment 消息,并将新的 Payment 作为参数传递。图 17.18 显示了一个可能反映这一点的部分交互图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Assume we need to create a Payment instance and associate it with the Sale. What class should be responsible for this? Since a Register "records" a Payment in the real-world domain, the Creator pattern suggests Register as a candidate for creating the Payment. The Register instance could then send an addPayment message to the Sale, passing along the new Payment as a parameter. A possible partial interaction diagram reflecting this is shown in Figure 17.18.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 17.18.Register 创建 Payment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这种职责分配将 Register 类与 Payment 类的知识耦合在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This assignment of responsibilities couples the Register class to knowledge of the Payment class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              应用 UML: 请注意,Payment 实例被显式命名为 p,因此在消息 2 中可以将其作为参数引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Applying UML: Note that the Payment instance is explicitly named p so that in message 2 it can be referenced as a parameter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 17.19 显示了创建 Payment 并将其与 Sale 关联的替代解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Figure 17.19 shows an alternative solution to creating the Payment and associating it with the Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 17.19.Sale 创建 Payment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                              根据职责分配,哪种设计支持低耦合?在这两种情况下,我们都假设 Sale 最终必须与 Payment 的知识相结合。设计 1 ,其中 Register 创建 Payment,添加了 RegisterPayment 的耦合;设计 2 中,Sale 创建 Payment,不会增加耦合。纯粹从耦合的角度来看,首选 Design 2,因为它保持了整体较低的耦合。此示例说明了两种模式Low Coupling 和 Creator 如何建议不同的解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Which design, based on assignment of responsibilities, supports Low Coupling? In both cases we assume the Sale must eventually be coupled to knowledge of a Payment. Design 1, in which the Register creates the Payment, adds coupling of Register to Payment; Design 2, in which the Sale does the creation of a Payment, does not increase the coupling. Purely from the point of view of coupling, prefer Design 2 because it maintains overall lower coupling. This example illustrates how two patternsLow Coupling and Creatormay suggest different solutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在实践中,不能单独考虑耦合水平,而脱离 Expert 和 High Cohesion 等其他原则。然而,这是改进设计时要考虑的一个因素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In practice, the level of coupling alone can't be considered in isolation from other principles such as Expert and High Cohesion. Nevertheless, it is one factor to consider in improving a design.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                              讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              低耦合是所有设计决策中要牢记的原则;这是一个需要不断考虑的基本目标。这是您在评估所有设计决策时应用的评估原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Low Coupling is a principle to keep in mind during all design decisions; it is an underlying goal to continually consider. It is an evaluative principle that you apply while evaluating all design decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在面向对象的语言(如 C++、Java 和 C#)中,从 TypeXTypeY 的常见耦合形式包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In object-oriented languages such as C++, Java, and C#, common forms of coupling from TypeX to TypeY include the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX 具有引用 TypeY 实例或 TypeY 本身的属性(数据成员或实例变量)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX has an attribute (data member or instance variable) that refers to a TypeY instance, or TypeY itself.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX 对象调用 TypeY 对象的服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • A TypeX object calls on services of a TypeY object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX 具有一个方法,该方法以任何方式引用 TypeY 的实例或 TypeY 本身。这些变量通常包括 TypeY 类型的参数或局部变量,或者从消息返回的对象是 TypeY 的实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX has a method that references an instance of TypeY, or TypeY itself, by any means. These typically include a parameter or local variable of type TypeY, or the object returned from a message being an instance of TypeY.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeXTypeY 的直接或间接子类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeX is a direct or indirect subclass of TypeY.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeY 是一个接口,TypeX 实现该接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • TypeY is an interface, and TypeX implements that interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              低耦合 鼓励您分配责任,以便其放置不会将耦合增加到导致高耦合可能产生的负面结果的水平。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Low Coupling encourages you to assign a responsibility so that its placement does not increase the coupling to a level that leads to the negative results that high coupling can produce.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Low Coupling 支持更独立的类设计,从而减少更改的影响。它不能与其他模式(如 Expert 和 High Cohesion)孤立地考虑,而是需要作为影响分配职责选择的几个设计原则之一。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Low Coupling supports the design of classes that are more independent, which reduces the impact of change. It can't be considered in isolation from other patterns such as Expert and High Cohesion, but rather needs to be included as one of several design principles that influence a choice in assigning a responsibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              子类与其 superclass 强耦合。仔细考虑从 superclass 派生的任何决定,因为它是一种非常强大的耦合形式。例如,假设对象必须持久存储在关系数据库或对象数据库中。在这种情况下,您可以遵循相对常见的设计实践,即创建一个名为 PersistentObject 的抽象超类,其他类从该超类派生。这种子类化的缺点是它将域对象高度耦合到特定的技术服务,并混合了不同的架构关注点,而优点是持久性行为的自动继承。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A subclass is strongly coupled to its superclass. Consider carefully any decision to derive from a superclass since it is such a strong form of coupling. For example, suppose that objects must be stored persistently in a relational or object database. In this case, you could follow the relatively common design practice of creating an abstract superclass called PersistentObject from which other classes derive. The disadvantage of this subclassing is that it highly couples domain objects to a particular technical service and mixes different architectural concerns, whereas the advantage is automatic inheritance of persistence behavior.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              您无法获得耦合何时过高的绝对度量。重要的是,您可以衡量当前的耦合程度,并评估增加耦合度是否会导致问题。通常,本质上是泛型且重用可能性高的类应该具有特别低的耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              You cannot obtain an absolute measure of when coupling is too high. What is important is that you can gauge the current degree of coupling and assess whether increasing it will lead to problems. In general, classes that are inherently generic in nature and with a high probability for reuse should have especially low coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Low Coupling 的极端情况是 class 之间没有耦合。这个案例冒犯了对象技术的核心隐喻:一个通过消息进行通信的互联对象系统。过度采用低耦合会产生一个糟糕的设计,其中包含一些不连贯、臃肿和复杂的有源对象来完成所有工作,并且有许多被动零耦合对象充当简单的数据存储库。类之间一定程度的耦合是正常的,并且对于创建面向对象的系统是必要的,在该系统中,任务是通过连接对象之间的协作来完成的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The extreme case of Low Coupling is no coupling between classes. This case offends against a central metaphor of object technology: a system of connected objects that communicate via messages. Low Coupling taken to excess yields a poor designone with a few incohesive, bloated, and complex active objects that do all the work, and with many passive zero-coupled objects that act as simple data repositories. Some moderate degree of coupling between classes is normal and necessary for creating an object-oriented system in which tasks are fulfilled by a collaboration between connected objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              与稳定元件和普遍元件的高度耦合很少成为问题。例如,J2EE 应用程序可以安全地将自身耦合到 Java 库(java.util 等),因为它们是稳定且广泛使用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              High coupling to stable elements and to pervasive elements is seldom a problem. For example, a J2EE application can safely couple itself to the Java libraries (java.util, and so on), because they are stable and widespread.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              选择你的战斗

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Pick Your Battles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              问题不在于高耦合本身;它与在某些维度上不稳定的元素(例如它们的接口、实现或仅仅存在)高度耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It is not high coupling per se that is the problem; it is high coupling to elements that are unstable in some dimension, such as their interface, implementation, or mere presence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这一点很重要: 作为设计人员,我们可以增加灵活性,封装细节和实现,并在系统的许多领域进行一般性的低耦合设计。但是,如果我们在没有现实动机的情况下努力“面向未来”或降低耦合,那么这并不是值得花费的时间。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is an important point: As designers, we can add flexibility, encapsulate details and implementations, and in general design for lower coupling in many areas of the system. But, if we put effort into "future proofing" or lowering the coupling when we have no realistic motivation, this is not time well spent.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              你必须选择降低耦合和封装事物的战斗。关注现实的高不稳定性或进化点。例如,在 NextGen 项目中,我们知道需要将不同的第三方税收计算器(具有独特的接口)连接到系统。因此,在这个变化点设计低耦合是可行的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              You must pick your battles in lowering coupling and encapsulating things. Focus on the points of realistic high instability or evolution. For example, in the NextGen project, we know that different third-party tax calculators (with unique interfaces) need to be connected to the system. Therefore, designing for low coupling at this variation point is practical.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 不受其他组件更改的影响

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • not affected by changes in other components

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 孤立地易于理解

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • simple to understand in isolation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 方便再利用

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • convenient to reuse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              背景

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Background

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              耦合和内聚是设计中真正的基本原则,所有软件开发人员都应该这样理解和应用。Larry Constantine 也是 1970 年代结构化设计的创始人,也是当前更多关注可用性工程的倡导者 [CL99],他在 1960 年代主要负责识别和传达作为关键原则的耦合和内聚 [Constantine68CMS74]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Coupling and cohesion are truly fundamental principles in design, and should be appreciated and applied as such by all software developers. Larry Constantine, also a founder of structured design in the 1970s and a current advocate of more attention to usability engineering [CL99], was primarily responsible in the 1960s for identifying and communicating coupling and cohesion as critical principles [Constantine68, CMS74].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Protected Variation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                17.13. 控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                17.13. Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UI 层之外的第一个对象接收和协调 (“控件”) 系统操作?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What first object beyond the UI layer receives and coordinates ("controls") a system operation?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 SSD 分析期间首次探索了系统操作。这些是我们系统上的主要输入事件。例如,当使用 POS 终端的收银员按下“End Sale”按钮时,他会生成一个系统事件,指示“销售已结束”。同样,当使用文字处理器的作者按下“拼写检查”按钮时,他会生成一个指示“执行拼写检查”的系统事件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                System operations were first explored during the analysis of SSD. These are the major input events upon our system. For example, when a cashier using a POS terminal presses the "End Sale" button, he is generating a system event indicating "the sale has ended." Similarly, when a writer using a word processor presses the "spell check" button, he is generating a system event indicating "perform a spell check."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                控制器是 UI 层之外负责接收或处理系统操作消息的第一个对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A controller is the first object beyond the UI layer that is responsible for receiving or handling a system operation message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                将责任分配给表示以下选项之一的类:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Assign the responsibility to a class representing one of the following choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 表示整个“系统”、“根对象”、软件运行在其中运行的设备或主要子系统这些都是 Facade 控制器的变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Represents the overall "system," a "root object," a device that the software is running within, or a major subsystemthese are all variations of a facade controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 表示发生系统事件的用例场景,通常命名为 <UseCaseName>Handler、<UseCaseName>Coordinator 或 <UseCaseName>Session(用例或会话控制器)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 对同一用例场景中的所有系统事件使用相同的控制器类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 非正式地,会话是与参与者对话的实例。会话可以是任意长度,但通常根据用例(用例会话)进行组织。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Represents a use case scenario within which the system event occurs, often named <UseCaseName>Handler, <UseCaseName>Coordinator, or <UseCaseName>Session (use case or session controller).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Use the same controller class for all system events in the same use case scenario.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Informally, a session is an instance of a conversation with an actor. Sessions can be of any length but are often organized in terms of use cases (use case sessions).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                推论: 请注意,“window”、“view” 和 “document” 类不在此列表中。此类不应完成与系统事件关联的任务;它们通常接收这些事件并将其委托给控制器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Corollary: Note that "window," "view," and "document" classes are not on this list. Such classes should not fulfill the tasks associated with system events; they typically receive these events and delegate them to a controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                有些人通过代码示例可以更好地理解应用此模式。请看第 309 页的 实现 部分,了解富客户端和 Web UI 的 Java 示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Some get a better sense of applying this pattern with code examples. Look ahead in the Implementation section on p. 309 for Java examples of both rich client and Web UIs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                NextGen 应用程序包含多个系统操作,如图 17.20 所示。此模型将系统本身显示为一个类(这是合法的,在建模时有时很有用)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The NextGen application contains several system operations, as illustrated in Figure 17.20. This model shows the system itself as a class (which is legal and sometimes useful when modeling).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.20.NextGen POS 应用程序的一些系统操作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在分析过程中,系统操作可能被分配给某些分析模型中的类 System,以指示它们是系统操作。但是,这并不意味着名为 System 的软件类在设计过程中满足它们。相反,在设计过程中,控制器类被分配了系统操作的责任(参见图 17.21)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                During analysis, system operations may be assigned to the class System in some analysis model, to indicate they are system operations. However, this does not mean that a software class named System fulfills them during design. Rather, during design, a controller class is assigned the responsibility for system operations (see Figure 17.21).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.21.什么对象应该是 enterItem 的控制器?



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁应该是 enterItemendSale 等系统事件的控制者?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who should be the controller for system events such as enterItem and endSale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                根据 Controller 模式,以下是一些选择:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                By the Controller pattern, here are some choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                表示整个 “system”、“root object”、设备或子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Represents the overall "system," "root object," device, or subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                收银机, POSSystem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Register, POSSystem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                表示用例场景的所有系统事件的接收者或处理程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Represents a receiver or handler of all system events of a use case scenario.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleHandler、ProcessSaleSession

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleHandler, ProcessSaleSession



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,在 POS 领域中,收银机(称为 POS 终端)是一种运行软件的专用设备。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Note that in the domain of POS, a Register (called a POS Terminal) is a specialized device with software running in it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在交互图方面,图 17.22 中的一个例子可能很有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In terms of interaction diagrams, one of the examples in Figure 17.22 could be useful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.22.控制器选择。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择这些类中哪一个是最合适的控制器受其他因素的影响,以下部分将探讨这些因素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The choice of which of these classes is the most appropriate controller is influenced by other factors, which the following section explores.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在设计过程中,在系统行为分析期间识别的系统操作被分配给一个或多个控制器类,例如 Register,如图 17.23 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                During design, the system operations identified during system behavior analysis are assigned to one or more controller classes, such as Register, as shown in Figure 17.23.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.23.系统操作的分配。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                有些人通过代码示例可以更好地理解应用此模式。请提前查看第 309 页的 实现 部分,了解富客户端和 Web UI 的 Java 示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Some get a better sense of applying this pattern with code examples. Look ahead in the Implementation section on p. 309 for examples in Java for both rich client and Web UIs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                简单地说,这是一种委托模式。根据 UI 层不应包含应用程序逻辑的理解,UI 层对象必须将工作请求委托给另一个层。当 “另一层” 是域层时,Controller 模式总结了您作为 OO 开发人员为接收工作请求的域对象委托所做的常见选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Simply, this is a delegation pattern. In accordance with the understanding that the UI layer shouldn't contain application logic, UI layer objects must delegate work requests to another layer. When the "other layer" is the domain layer, the Controller pattern summarizes common choices that you, as an OO developer, make for the domain object delegate that receives the work requests.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                系统接收外部输入事件,通常涉及由人员操作的 GUI。其他输入媒介包括外部消息(例如在呼叫处理电信开关中)或来自传感器的信号(例如在过程控制系统中)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Systems receive external input events, typically involving a GUI operated by a person. Other mediums of input include external messages, such as in a call-processing telecommunications switch or signals from sensors such as in process control systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在所有情况下,都必须为这些事件选择处理程序。转向 Controller 模式,以获取有关普遍接受的合适选择的指导。如图 17.21 所示,控制器是从 UI 层进入域层的一种门面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In all cases, you must choose a handler for these events. Turn to the Controller pattern for guidance toward generally accepted, suitable choices. As illustrated in Figure 17.21, the controller is a kind of facade into the domain layer from the UI layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                您经常希望对一个用例的所有系统事件使用相同的控制器类,以便控制器可以维护有关用例状态的信息。例如,此类信息可用于识别无序的系统事件(例如,endSale 操作之前的 makePayment 操作)。不同的控制器可用于不同的用例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                You will often want to use the same controller class for all the system events of one use case so that the controller can maintain information about the state of the use case. Such information is useful, for example, to identify out-of-sequence system events (for example, a makePayment operation before an endSale operation). Different controllers may be used for different use cases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                控制器设计中的一个常见缺陷是由于责任分配过度造成的。然后,控制器会出现不良 (低) 内聚,违反了高内聚原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A common defect in the design of controllers results from over-assignment of responsibility. A controller then suffers from bad (low) cohesion, violating the principle of High Cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                通常,控制器应将需要完成的工作委托给其他对象;它协调或控制活动。它本身不会做太多工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Normally, a controller should delegate to other objects the work that needs to be done; it coordinates or controls the activity. It does not do much work itself.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请参阅“问题和解决方案”部分进行详细说明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Please see the "Issues and Solutions" section for elaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                第一类控制器是代表整个系统、设备或子系统的 Facade 控制器。这个想法是选择一些类名,该类名暗示了应用程序其他层的覆盖或门面,并提供从 UI 层到其他层的服务调用的主要点。门面可以是整个物理单元的抽象,例如 Register[12] 、TelecommSwitch、PhoneRobot;表示整个软件系统的类,例如 POSSystem;或设计师选择表示整个系统或子系统的任何其他概念,甚至,例如,如果它是游戏软件,则为 ChessGame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The first category of controller is a facade controller representing the overall system, device, or a subsystem. The idea is to choose some class name that suggests a cover, or facade, over the other layers of the application and that provides the main point of service calls from the UI layer down to other layers. The facade could be an abstraction of the overall physical unit, such as a Register[12] , TelecommSwitch, Phone, or Robot; a class representing the entire software system, such as POSSystem; or any other concept which the designer chooses to represent the overall system or a subsystem, even, for example, ChessGame if it was game software.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [12] 物理 POS 单元使用了各种术语,包括收银机、销售点终端 (POST) 等。随着时间的推移,“收银机”已经体现了物理单位的概念和登记销售和付款的事物的逻辑抽象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [12] Various terms are used for a physical POS unit, including register, point-of-sale terminal (POST), and so forth. Over time, "register" has come to embody the notion of both a physical unit and the logical abstraction of the thing that registers sales and payments.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当系统事件 “太多” 没有,或者用户界面 (UI) 无法将系统事件消息重定向到交替控制器(例如在消息处理系统中)时,外观控制器是合适的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Facade controllers are suitable when there are not "too many" system events, or when the user interface (UI) cannot redirect system event messages to alternating controllers, such as in a message-processing system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如果您选择一个使用案例控制器,则每个使用案例将具有不同的控制器。请注意,这种控制器不是域对象;它是一个支持系统的人工结构(就 GRASP 模式而言的纯制造)。例如,如果 NextGen 应用程序包含 Process SaleHandle Returns 等使用案例,则可能存在 ProcessSaleHandler 类等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you choose a use case controller, then you will have a different controller for each use case. Note that this kind of controller is not a domain object; it is an artificial construct to support the system (a Pure Fabrication in terms of the GRASP patterns). For example, if the NextGen application contains use cases such as Process Sale and Handle Returns, then there may be a ProcessSaleHandler class and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                何时应选择用例控制器?当将责任放在立面控制器中会导致设计具有低内聚或高耦合时,请考虑将其作为替代方案,通常是当立面控制器因过多责任而变得“臃肿”时。当不同进程中有许多系统事件时,用例控制器是一个不错的选择;它将它们的处理分解为可管理的单独类,并为了解和推理当前正在进行的方案的状态提供了基础。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When should you choose a use case controller? Consider it an alternative when placing the responsibilities in a facade controller leads to designs with low cohesion or high coupling, typically when the facade controller is becoming "bloated" with excessive responsibilities. A use case controller is a good choice when there are many system events across different processes; it factors their handling into manageable separate classes and also provides a basis for knowing and reasoning about the state of the current scenario in progress.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 UP 和 Jacobson 的旧 Objectory 方法 [Jacobson92] 中,存在边界、控制和实体类的(可选)概念。边界对象是接口的抽象,实体对象是独立于应用程序(通常是持久的)域软件对象,控制对象是用例处理程序,如此控制器模式中所述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the UP and Jacobson's older Objectory method [Jacobson92], there are the (optional) concepts of boundary, control, and entity classes. Boundary objects are abstractions of the interfaces, entity objects are the application-independent (and typically persistent) domain software objects, and control objects are use case handlers as described in this Controller pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Controller 模式的一个重要推论是 UI 对象(例如,窗口或按钮对象)和 UI 层不应负责实现系统事件。换句话说,系统操作应该在对象的 application logic 或 domain 层中处理,而不是在系统的 UI 层中处理。有关示例,请参阅“问题和解决方案”部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A important corollary of the Controller pattern is that UI objects (for example, window or button objects) and the UI layer should not have responsibility for fulfilling system events. In other words, system operations should be handled in the application logic or domain layers of objects rather than in the UI layer of a system. See the "Issues and Solutions" section for an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                控制器的 Web UI 和服务器端应用程序

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Web UIs and Server-Side Application of Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请参阅第 310 页,了解使用 Java Struts(一种流行的框架)的服务器端示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Please see p. 310 for a server-side example using Java Strutsa popular framework.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                类似的委派方法可以在 ASP.NET 和 Web Forms 中使用:包含 Web 浏览器按钮单击事件处理程序的“代码隐藏”文件将获得对域控制器对象的引用(例如,POS 案例研究中的 Register 对象),然后委派工作请求。这与 ASP.NET 编程的常见、脆弱的风格形成鲜明对比,在这种风格中,开发人员将应用程序逻辑处理插入到“代码隐藏”文件中,从而将应用程序逻辑混合到 UI 层中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A similar delegation approach can be used in ASP.NET and WebForms: The "code behind" file that contains event handlers for Web browser button clicks will obtain a reference to a domain controller object (e.g., a Register object in the POS case study), and then delegate the request for work. This is in contrast to the common, fragile style of ASP.NET programming in which developers insert application logic handling in the "code behind" file, thus mixing application logic into the UI layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                服务器端 Web UI 框架(如 Struts)体现了 Web-MVC(模型-视图-控制器)模式的概念。Web-MVC 中的“控制器”与此 GRASP 控制器不同。前者是 UI 层的一部分,控制 UI 交互和页面流。GRASP 控制器是域层的一部分,控制或协调工作请求的处理,基本上不知道正在使用什么 UI 技术(例如,Web UI、Swing UI 等)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Server-side Web UI frameworks (such as Struts) embody the concept of the Web-MVC (Model-View-Controller) pattern. The "controller" in Web-MVC differs from this GRASP controller. The former is part of the UI layer and controls the UI interaction and page flow. The GRASP controller is part of the domain layer and controls or coordinates the handling of the work request, essentially unaware of what UI technology is being used (e.g., a Web UI, a Swing UI, …).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用 Java 技术时,服务器端设计中还常见的是从 Web UI 层(例如,从 Struts Action 类)委托给 Enterprise JavaBeans (EJBSession 对象。Controller 模式的变体 #2表示用户会话或用例场景的对象涵盖了这种情况。在这种情况下,EJB Session 对象本身可以进一步委托到对象的域层,同样,您可以应用 Controller 模式在纯域层中选择合适的接收器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Also common with server-side designs when Java technologies are used is delegation from the Web UI layer (e.g., from a Struts Action class) to an Enterprise JavaBeans (EJB) Session object. Variant #2 of the Controller patternan object representing a user session or use case scenariocovers this case. In this case, the EJB Session object may itself delegate farther on to the domain layer of objects, and again, you can apply the Controller pattern to choose a suitable receiver in the pure domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                综上所述,服务器端系统操作的适当处理受到所选服务器技术框架的强烈影响,并且仍然是一个不断变化的目标。但是 Model-View Separation 的基本原则可以而且仍然适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                All that said, the appropriate handling of server-side systems operations is strongly influenced by the chosen server technical frameworks and continues to be a moving target. But the underlying principle of Model-View Separation can and does still apply.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                即使使用与服务器交互的富客户端 UI(例如,Swing UI),控制器模式仍然适用。客户端 UI 将请求转发到本地客户端控制器,控制器将全部或部分请求处理转发到远程服务。这种设计降低了 UI 与远程服务的耦合,并使其更容易,例如,通过客户端控制器的间接方式在本地或远程提供服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Even with a rich-client UI (e.g., a Swing UI) that interacts with a server, the Controller pattern still applies. The client-side UI forwards the request to the local client-side controller, and the controller forwards all or part of the request handling to remote services. This design lowers the coupling of the UI to remote services and makes it easier, for example, to provide the services either locally or remotely, through the indirection of the client-side controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 增加重用可插拔接口的可能性这些好处确保应用程序逻辑不在接口层中处理。控制器的职责在技术上可以在 interface 对象中处理,但这样的设计意味着程序代码和应用程序逻辑的实现将嵌入到 interface 或 window 对象中。interface-as-controller 设计减少了在未来应用程序中重用 logic 的机会,因为绑定到特定 interface (例如,类似 window-objects) 的 logic 很少适用于其他应用程序。相比之下,将系统操作责任委托给控制器支持在未来应用程序中重用 logic 。并且由于应用程序逻辑未绑定到接口层,因此可以将其替换为不同的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Increased potential for reuse and pluggable interfaces These benefits ensure that application logic is not handled in the interface layer. The responsibilities of a controller could technically be handled in an interface object, but such a design implies that program code and the fulfillment of application logic would be embedded in interface or window objects. An interface-as-controller design reduces the opportunity to reuse logic in future applications, since logic that is bound to a particular interface (for example, window-like objects) is seldom applicable in other applications. By contrast, delegating a system operation responsibility to a controller supports the reuse of the logic in future applications. And since the application logic is not bound to the interface layer, it can be replaced with a different interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 有机会推断用例的状态有时,我们必须确保系统操作按合法顺序进行,或者我们希望能够推断正在进行的用例中活动和操作的当前状态。例如,我们可能必须保证 makePayment 操作在 endSale 操作发生之前不会发生。如果是这样,我们需要在某个地方捕获此状态信息;控制器是一个合理的选择,特别是如果我们在整个用例中使用相同的控制器(按照推荐)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Opportunity to reason about the state of the use case Sometimes we must ensure that system operations occur in a legal sequence, or we want to be able to reason about the current state of activity and operations within the use case that is underway. For example, we may have to guarantee that the makePayment operation cannot occur until the endSale operation has occurred. If so, we need to capture this state information somewhere; the controller is one reasonable choice, especially if we use the same controller throughout the use case (as recommended).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                以下示例将 Java 技术用于两种常见情况,即 Java Swing 中的富客户端和服务器上带有 Struts 的 Web UI(Servlet 引擎)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The following examples use Java technologies for two common cases, a rich client in Java Swing and a Web UI with Struts on the server (a Servlet engine).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,您应该在 .NET WinForms 和 ASP.NET WebForms 中应用类似的方法。在设计良好的 .NET 中(经常被违反模型-视图分离原则的 MS 程序员忽略)中的一种良好做法是不要在事件处理程序或“代码隐藏”文件(两者都是 UI 层的一部分)中插入应用程序逻辑代码。相反,在 .NET 事件处理程序或“代码隐藏”文件中,只需获取对域对象(例如 Register 对象)的引用,并委托给它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Please note that you should apply a similar approach in .NET WinForms and ASP.NET WebForms. A good practice in well-designed .NET (often ignored by MS programmers who violate the Model-View Separation Principle) is to not insert application logic code in the event handlers or in the "code behind" files (those are both part of the UI layer). Rather, in the .NET event handlers or "code behind" files, simply obtain a reference to a domain object (e.g., a Register object), and delegate to it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用 Java Swing 实现:富客户端 UI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Implementation with Java Swing: Rich Client UI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                本节假定您熟悉基本的 Swing。该代码包含用于解释关键点的注释。一些注释:请注意ProcessSaleJFrame 窗口具有对域控制器对象 Register 的引用。At I 定义按钮单击的处理程序。在 I show key message将 enterItem 消息发送到域层中的控制器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This section assumes you are familiar with basic Swing. The code contains comments to explain the key points. A few comments: Notice at that the ProcessSaleJFrame window has a reference to the domain controller object, the Register. At I define the handler for the button click. At I show the key messagesending the enterItem message to the controller in the domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    package com.craiglarman.nextgen.ui.swing;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // imports…
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // in Java, a JFrame is a typical window
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public class ProcessSaleJFrame extends JFrame
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // the window has a reference to the 'controller' domain object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  private Register register;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // the window is passed the register, on creation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public ProcessSaleJFrame(Register _register)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       register = _register;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // this button is clicked to perform the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // system operation "enterItem"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    private JButton BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // this is the important method!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // here i show the message from the UI layer to domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    private JButton getBTN_ENTER_ITEM()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // does the button exist?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       if (BTN_ENTER_ITEM != null)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          return BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ELSE button needs to be initialized...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       BTN_ENTER_ITEM = new JButton();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       BTN_ENTER_ITEM.setText("Enter Item");
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // THIS IS THE KEY SECTION!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // in Java, this is how you define
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // a click handler for a button
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  BTN_ENTER_ITEM.addActionListener(new ActionListener()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public void actionPerformed(ActionEvent e)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // Transformer is a utility class to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // transform Strings to other data types
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // because the JTextField GUI widgets have Strings
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ItemID id = Transformer.toItemID(getTXT_ID().getText());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           int qty = Transformer.toInt(getTXT_QTY().getText());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // here we cross the boundary from the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // UI layer to the domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // delegate to the 'controller'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // > > > THIS IS THE KEY STATEMENT < < <
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         register.enterItem(id, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        } ); // end of the addActionListener call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     } // end of method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    package com.craiglarman.nextgen.ui.swing;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // imports…
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // in Java, a JFrame is a typical window
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public class ProcessSaleJFrame extends JFrame
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // the window has a reference to the 'controller' domain object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  private Register register;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // the window is passed the register, on creation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public ProcessSaleJFrame(Register _register)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       register = _register;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // this button is clicked to perform the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // system operation "enterItem"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    private JButton BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // this is the important method!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // here i show the message from the UI layer to domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    private JButton getBTN_ENTER_ITEM()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // does the button exist?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       if (BTN_ENTER_ITEM != null)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          return BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ELSE button needs to be initialized...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       BTN_ENTER_ITEM = new JButton();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       BTN_ENTER_ITEM.setText("Enter Item");
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // THIS IS THE KEY SECTION!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // in Java, this is how you define
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // a click handler for a button
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  BTN_ENTER_ITEM.addActionListener(new ActionListener()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public void actionPerformed(ActionEvent e)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // Transformer is a utility class to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // transform Strings to other data types
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // because the JTextField GUI widgets have Strings
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ItemID id = Transformer.toItemID(getTXT_ID().getText());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           int qty = Transformer.toInt(getTXT_QTY().getText());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // here we cross the boundary from the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // UI layer to the domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // delegate to the 'controller'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // > > > THIS IS THE KEY STATEMENT < < <
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         register.enterItem(id, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        } ); // end of the addActionListener call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return BTN_ENTER_ITEM;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     } // end of method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用 Java Struts 实现:客户端浏览器和 WebUI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Implementation with Java Struts: Client Browser and WebUI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                本部分假定您熟悉基本的 Strut。请注意,要在服务器端获取对 Register 域对象的引用,Action 对象必须深入研究 Servlet 上下文。在 I show key message将 enterItem 消息发送到域层中的域控制器对象时。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This section assumes you are familiar with basic Struts. Notice at that to obtain a reference to the Register domain object on the server side, the Action object must dig into the Servlet context. At I show the key messagesending the enterItem message to the domain controller object in the domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  package com.craiglarman.nextgen.ui.web;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // … imports
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // in Struts, an Action object is associated with a
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // web browser button click, and invoked (on the server)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // when the button is clicked.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class EnterItemAction extends Action {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // this is the method invoked on the server
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // when the button is clicked on the client browser
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public ActionForward execute( ActionMapping mapping,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ActionForm form,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  HttpServletRequest request,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  HttpServletResponse response )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                throws Exception
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // the server has a Repository object that
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // holds references to several things, including
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // the POS "register" object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Repository repository = (Repository)getServlet().
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        getServletContext().getAttribute(Constants.REPOSITORY_KEY);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Register register = repository.getRegister();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // extract the itemID and qty from the web form
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     String txtId = ((SaleForm)form).getItemID();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     String txtQty = ((SaleForm)form).getQuantity();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // Transformer is a utility class to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // transform Strings to other data types
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     ItemID id = Transformer.toItemID(txtId);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int qty = Transformer.toInt(txtQty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // here we cross the boundary from the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // UI layer to the domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // delegate to the 'domain controller'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // > > > THIS IS THE KEY STATEMENT < < <
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     register.enterItem(id, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  package com.craiglarman.nextgen.ui.web;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // … imports
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // in Struts, an Action object is associated with a
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // web browser button click, and invoked (on the server)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // when the button is clicked.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class EnterItemAction extends Action {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // this is the method invoked on the server
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // when the button is clicked on the client browser
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public ActionForward execute( ActionMapping mapping,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ActionForm form,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  HttpServletRequest request,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  HttpServletResponse response )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                throws Exception
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // the server has a Repository object that
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // holds references to several things, including
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // the POS "register" object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Repository repository = (Repository)getServlet().
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        getServletContext().getAttribute(Constants.REPOSITORY_KEY);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Register register = repository.getRegister();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // extract the itemID and qty from the web form
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     String txtId = ((SaleForm)form).getItemID();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     String txtQty = ((SaleForm)form).getQuantity();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // Transformer is a utility class to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // transform Strings to other data types
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     ItemID id = Transformer.toItemID(txtId);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int qty = Transformer.toInt(txtQty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // here we cross the boundary from the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // UI layer to the domain layer
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // delegate to the 'domain controller'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // > > > THIS IS THE KEY STATEMENT < < <
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     register.enterItem(id, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                臃肿的控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Bloated Controllers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                问题和解决方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Issues and Solutions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                设计不佳,控制器类将具有低内聚力未聚焦并处理太多责任区域;这称为 bloated controller。腹胀的迹象是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Poorly designed, a controller class will have low cohesionunfocused and handling too many areas of responsibility; this is called a bloated controller. Signs of bloating are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 只有一个控制器类接收系统中的所有系统事件,并且有很多 controller 事件。如果选择了 Facade 控制器,有时会发生这种情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • There is only a single controller class receiving all system events in the system, and there are many of them. This sometimes happens if a facade controller is chosen.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 控制器本身执行完成系统事件所需的许多任务,而无需委派工作。这通常涉及违反 Information Expert 和 High Cohesion。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The controller itself performs many of the tasks necessary to fulfill the system event, without delegating the work. This usually involves a violation of Information Expert and High Cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 控制器具有许多属性,并且它维护有关系统或域的重要信息,这些信息应该已分发给其他对象,或者它与在其他位置找到的信息重复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A controller has many attributes, and it maintains significant information about the system or domain, which should have been distributed to other objects, or it duplicates information found elsewhere.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                控制器臃肿的治疗方法包括以下两种:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Among the cures for a bloated controller are these two:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 添加更多控制器系统不必只需要一个。使用 Use Case 控制器,而不是 Facade 控制器。例如,考虑一个具有许多系统事件的应用程序,例如航空公司预订系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  它可能包含以下控制器:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  用例控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MakeReservationHandler

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ManageSchedulesHandler

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ManageFaresHandler



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. Add more controllersa system does not have to need only one. Instead of facade controllers, employ use case controllers. For example, consider an application with many system events, such as an airline reservation system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  It may contain the following controllers:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Use case controllers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MakeReservationHandler

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ManageSchedulesHandler

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ManageFaresHandler



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. 设计控制器,使其主要将每个系统操作责任的履行委托给其他对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. Design the controller so that it primarily delegates the fulfillment of each system operation responsibility to other objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UI 层不处理系统事件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UI Layer Does Not Handle System Events

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                重申一下:Controller 模式的一个重要推论是 UI 对象(例如,窗口对象)和 UI 层不应负责处理系统事件。例如,考虑使用 JFrame 显示信息的 Java 设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To reiterate: An important corollary of the Controller pattern is that UI objects (for example, window objects) and the UI layer should not have responsibility for handling system events. As an example, consider a design in Java that uses a JFrame to display the information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                假设 NextGen 应用程序有一个窗口,用于显示销售信息并捕获收银员操作。使用 Controller 模式,图 17.24 说明了 JFrame 和控制器以及 POS 系统的一部分中的其他对象之间的可接受关系(进行了简化)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Assume the NextGen application has a window that displays sale information and captures cashier operations. Using the Controller pattern, Figure 17.24 illustrates an acceptable relationship between the JFrame and the controller and other objects in a portion of the POS system (with simplifications).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.24.UI 层与域层的理想耦合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,UI 层的 SaleJFrame 类部分将 enterItem 请求委托给 Register 对象。它没有参与处理操作或决定如何处理它;窗口仅将其委托给另一个层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Notice that the SaleJFrame classpart of the UI layerdelegates the enterItem request to the Register object. It did not get involved in processing the operation or deciding how to handle it; the window only delegated it to another layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                通过使用 Controller 模式而不是 UI 层,将系统操作的责任分配给应用程序层或域层中的对象,可以提高重用潜力。如果 UI 层对象(如 SaleJFrame)处理表示业务流程一部分的系统操作,则业务流程逻辑将包含在接口(例如,类似窗口的)对象中;然后,由于业务逻辑与特定接口和应用程序的耦合,重用业务逻辑的机会就会减少。因此,图 17.25 中的设计是不可取的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Assigning the responsibility for system operations to objects in the application or domain layer by using the Controller pattern rather than the UI layer can increase reuse potential. If a UI layer object (like the SaleJFrame) handles a system operation that represents part of a business process, then business process logic would be contained in an interface (for example, window-like) object; the opportunity for reuse of the business logic then diminishes because of its coupling to a particular interface and application. Consequently, the design in Figure 17.25 is undesirable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 17.25.接口层与域层的耦合不太理想。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                将系统操作责任放在域对象控制器中,可以更轻松地在将来的应用程序中重用支持关联业务流程的程序逻辑。它还可以更轻松地拔下 UI 层并使用不同的 UI 框架或技术,或者以脱机 “批处理” 模式运行系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Placing system operation responsibility in a domain object controller makes it easier to reuse the program logic supporting the associated business process in future applications. It also makes it easier to unplug the UI layer and use a different UI framework or technology, or to run the system in an offline "batch" mode.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                消息处理系统和命令模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Message Handling Systems and the Command Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                某些应用程序是消息处理系统或服务器,它们接收来自其他进程的请求。电信交换机就是一个常见的例子。在此类系统中,接口和控制器的设计略有不同。细节将在后面的章节中探讨,但从本质上讲,一种常见的解决方案是使用第 38 章中介绍的命令模式 [GHJV95] 和命令处理器模式 [BMRSS96]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Some applications are message-handling systems or servers that receive requests from other processes. A telecommunications switch is a common example. In such systems, the design of the interface and controller is somewhat different. The details are explored in a later chapter, but in essence, a common solution is to use the Command pattern [GHJV95] and Command Processor pattern [BMRSS96], introduced in Chapter 38.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 命令在消息处理系统中,每条消息都可以由单独的 Command 对象 [GHJV95] 表示和处理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Command In a message-handling system, each message may be represented and handled by a separate Command object [GHJV95].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 外观立面控制器是 Facade [GHJV95] 的一种。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Facade A facade controller is a kind of Facade [GHJV95].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 这是一个 POSA 模式 [BMRSS96]。将域逻辑放在域层而不是表示层是 Layers 模式的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Layers This is a POSA pattern [BMRSS96]. Placing domain logic in the domain layer rather than the presentation layer is part of the Layers pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 纯制造此 GRASP 模式是设计器的任意创建,而不是其名称受域模型启发的软件类。用例控制器是一种 Pure Fabrication。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Pure Fabrication This GRASP pattern is an arbitrary creation of the designer, not a software class whose name is inspired by the Domain Model. A use case controller is a kind of Pure Fabrication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  17.14. 高内聚

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  17.14. High Cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如何保持对象的焦点、可理解性和可管理性,并作为副作用支持 Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  How to keep objects focused, understandable, and manageable, and as a side effect, support Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  就对象设计而言,内聚(或更具体地说,功能内聚)是衡量元素职责的相关性和集中度的指标。具有高度相关职责但不执行大量工作的元素具有很高的内聚力。这些元素包括类、子系统等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In terms of object design, cohesion (or more specifically, functional cohesion) is a measure of how strongly related and focused the responsibilities of an element are. An element with highly related responsibilities that does not do a tremendous amount of work has high cohesion. These elements include classes, subsystems, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  分配一项责任,以保持高度凝聚力。使用它来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Assign a responsibility so that cohesion remains high. Use this to evaluate alternatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  内聚度低的类会做很多不相关的事情,或者做太多的工作。这样的类是不可取的;他们存在以下问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A class with low cohesion does many unrelated things or does too much work. Such classes are undesirable; they suffer from the following problems:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 难以理解

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • hard to comprehend

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 难以重复使用

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • hard to reuse

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 难以维护

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • hard to maintain

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 嫩;不断受到变化的影响

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • delicate; constantly affected by change

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  低内聚类通常表示非常 “大颗粒” 的抽象,或者承担了本应委托给其他对象的责任。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Low cohesion classes often represent a very "large grain" of abstraction or have taken on responsibilities that should have been delegated to other objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  让我们再看一下 Low Coupling 模式中使用的示例问题,并针对 High Cohesion 对其进行分析。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Let's take another look at the example problem used in the Low Coupling pattern and analyze it for High Cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  假设我们需要创建一个 (cash) Payment 实例并将其与 Sale 关联。哪个类应该对此负责?由于 Register 在实际域中记录了 Payment,因此 Creator 模式建议 Register 作为创建 Payment 的候选者。然后,Register 实例可以向 Sale 发送 addPayment 消息,将新的 Payment 作为参数传递,如图 17.26 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Assume we have a need to create a (cash) Payment instance and associate it with the Sale. What class should be responsible for this? Since Register records a Payment in the real-world domain, the Creator pattern suggests Register as a candidate for creating the Payment. The Register instance could then send an addPayment message to the Sale, passing along the new Payment as a parameter, as shown in Figure 17.26.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 17.26.Register 创建 Payment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这种责任分配将付款的责任置于 Register 中。The Register 承担了履行 makePayment 系统操作的部分责任。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This assignment of responsibilities places the responsibility for making a payment in the Register. The Register is taking on part of the responsibility for fulfilling the makePayment system operation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在这个孤立的示例中,这是可以接受的;但是如果我们继续让 Register 类负责执行与越来越多的系统操作相关的部分或大部分工作,它将变得越来越繁重的任务,并且变得不连贯。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In this isolated example, this is acceptable; but if we continue to make the Register class responsible for doing some or most of the work related to more and more system operations, it will become increasingly burdened with tasks and become incohesive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  想象一下 50 个系统操作,全部由 Register 接收。如果 Register 执行了与每个对象相关的工作,它将成为一个“臃肿”的不连贯对象。关键不在于这个单一的 Payment 创建任务本身使 Register 变得不连贯,而是作为整体责任分配的更大图景的一部分,它可能表明一种低凝聚力的趋势。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Imagine fifty system operations, all received by Register. If Register did the work related to each, it would become a "bloated" incohesive object. The point is not that this single Payment creation task in itself makes the Register incohesive, but as part of a larger picture of overall responsibility assignment, it may suggest a trend toward low cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  就发展对象设计师的技能而言,无论最终的设计选择如何,最重要的是宝贵的成就,至少我们知道要考虑对内聚力的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  And most important in terms of developing skills as object designers, regardless of the final design choice, is the valuable achievement that at least we know to consider the impact on cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  相比之下,如图 17.27 所示,第二种设计将支付创建责任委托给 Sale 支持,在 Register 中具有更高的内聚力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  By contrast, as shown in Figure 17.27, the second design delegates the payment creation responsibility to the Sale supports higher cohesion in the Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 17.27.Sale 创建 Payment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  由于第二种设计同时支持高内聚和低耦合,因此这是可取的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Since the second design supports both high cohesion and low coupling, it is desirable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在实践中,不能单独考虑凝聚力的级别,而脱离其他职责和其他原则,如专家和低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In practice, the level of cohesion alone can't be considered in isolation from other responsibilities and other principles such as Expert and Low Coupling.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  与低耦合一样,高内聚是所有设计决策中要牢记的原则;这是一个需要不断考虑的基本目标。这是设计人员在评估所有设计决策时应用的评估原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Like Low Coupling, High Cohesion is a principle to keep in mind during all design decisions; it is an underlying goal to continually consider. It is an evaluative principle that a designer applies while evaluating all design decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Grady Booch 将高功能内聚描述为当组件的元素(例如类)“协同工作以提供一些边界良好的行为”时存在 [Booch94]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Grady Booch describes high functional cohesion as existing when the elements of a component (such as a class) "all work together to provide some well-bounded behavior" [Booch94].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  以下是一些说明不同程度的功能内聚的方案:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Here are some scenarios that illustrate varying degrees of functional cohesion:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 极低的内聚力一个类只负责非常不同的功能领域的许多事情。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设存在一个名为 RDB-RPC-Interface 的类,该类完全负责与关系数据库交互和处理远程过程调用。这是两个截然不同的功能区域,每个区域都需要大量的支持代码。职责应分为与 RDB 访问相关的类系列和与 RPC 支持相关的系列。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Very low cohesion A class is solely responsible for many things in very different functional areas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Assume the existence of a class called RDB-RPC-Interface which is completely responsible for interacting with relational databases and for handling remote procedure calls. These are two vastly different functional areas, and each requires lots of supporting code. The responsibilities should be split into a family of classes related to RDB access and a family related to RPC support.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 低内聚类只负责一个功能区域中的复杂任务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设存在一个名为 RDBInterface 的类,该类完全负责与关系数据库交互。该类的方法都是相关的,但有很多方法,并且有大量的支持代码;可能有成百上千种方法。该类应拆分为一系列轻量级类,共享工作以提供 RDB 访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Low cohesion A class has sole responsibility for a complex task in one functional area.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Assume the existence of a class called RDBInterface which is completely responsible for interacting with relational databases. The methods of the class are all related, but there are lots of them, and a tremendous amount of supporting code; there may be hundreds or thousands of methods. The class should split into a family of lightweight classes sharing the work to provide RDB access.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 高内聚力类在一个功能区域中具有中等职责,并与其他类协作完成任务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设存在一个名为 RDBInterface 的类,该类仅部分负责与关系数据库交互。它与十几个与 RDB 访问相关的其他类进行交互,以便检索和保存对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. High cohesion A class has moderate responsibilities in one functional area and collaborates with other classes to fulfill tasks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Assume the existence of a class called RDBInterface that is only partially responsible for interacting with relational databases. It interacts with a dozen other classes related to RDB access in order to retrieve and save objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7. 中等内聚力类在几个不同的领域中具有轻量级的唯一职责,这些领域在逻辑上与类概念相关,但彼此无关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设存在一个名为 Company 的类,该类完全负责 (a) 了解其员工和 (b) 了解其财务信息。这两个领域彼此之间没有很强的相关性,尽管两者都在逻辑上与公司的概念相关。此外,公共方法的总数很少,支持的代码量也很少。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  8. Moderate cohesion A class has lightweight and sole responsibilities in a few different areas that are logically related to the class concept but not to each other.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Assume the existence of a class called Company that is completely responsible for (a) knowing its employees and (b) knowing its financial information. These two areas are not strongly related to each other, although both are logically related to the concept of a company. In addition, the total number of public methods is small, as is the amount of supporting code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  根据经验,具有高内聚性的类具有相对较少的方法,具有高度相关的功能,并且不会执行太多工作。如果任务很大,它会与其他对象协作以分担工作量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As a rule of thumb, a class with high cohesion has a relatively small number of methods, with highly related functionality, and does not do too much work. It collaborates with other objects to share the effort if the task is large.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  具有高内聚性的类是有利的,因为它相对容易维护、理解和重用。高度的相关功能,结合少量的操作,还简化了维护和增强。高度相关的功能细粒度还支持更高的重用潜力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A class with high cohesion is advantageous because it is relatively easy to maintain, understand, and reuse. The high degree of related functionality, combined with a small number of operations, also simplifies maintenance and enhancements. The fine grain of highly related functionality also supports increased reuse potential.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  与对象技术中的许多事物一样,高内聚模式有一个现实世界的类比。一个普遍的观察结果是,如果一个人承担了太多不相关的责任,尤其是那些应该适当委派给其他人的责任,那么这个人就没有效率。这在一些没有学会如何授权的经理身上观察到。这些人的凝聚力很低;他们已经准备好变得 “unglued”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The High Cohesion patternlike many things in object technologyhas a real-world analogy. It is a common observation that if a person takes on too many unrelated responsibilitiesespecially ones that should properly be delegated to othersthen the person is not effective. This is observed in some managers who have not learned how to delegate. These people suffer from low cohesion; they are ready to become "unglued."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  另一个经典原则:模块化设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Another Classic Principle: Modular Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  耦合和内聚是软件设计中的旧原则;使用 Objects 进行设计并不意味着忽视公认的基本原则。其中另一个与耦合和内聚密切相关的是促进模块化设计。引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Coupling and cohesion are old principles in software design; designing with objects does not imply ignoring well-established fundamentals. Another of thesewhich is strongly related to coupling and cohesionis to promote modular design. To quote:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  模块化是一个系统的属性,它被分解成一组内聚的、松散耦合的模块 [Booch94]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Modularity is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules [Booch94].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们通过创建具有高内聚性的方法和类来促进模块化设计。在基本对象级别,我们通过设计具有明确、单一目的的每个方法,并将一组相关的关注点分组到一个类中来实现模块化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We promote a modular design by creating methods and classes with high cohesion. At the basic object level, we achieve modularity by designing each method with a clear, single purpose and by grouping a related set of concerns into a class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  内聚和耦合;阴阳

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Cohesion and Coupling; Yin and Yang

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  不良的内聚通常会导致不良的耦合,反之亦然。我把内聚和耦合称为软件工程的阴阳,因为它们具有相互依存的影响。例如,考虑一个 GUI 小部件类,该类表示和绘制小部件,将数据保存到数据库,并调用远程对象服务。它不仅非常不连贯,而且与许多(和不同的)元素耦合在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Bad cohesion usually begets bad coupling, and vice versa. I call cohesion and coupling the yin and yang of software engineering because of their interdependent influence. For example, consider a GUI widget class that represents and paints a widget, saves data to a database, and invokes remote object services. Not only is it profoundly incohesive, but it is coupled to many (and disparate) elements.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在少数情况下,接受较低的内聚力是合理的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In a few cases, accepting lower cohesion is justified.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  一种情况是将职责或代码分组到一个类或组件中,以简化一个人的维护,但要注意,这种分组也可能使维护恶化。但是,假设一个应用程序包含嵌入式 SQL 语句,根据其他良好的设计原则,这些语句应该分布在 10 个类中,比如 10 个 “数据库映射器” 类。现在,通常只有一两个 SQL 专家知道如何最好地定义和维护此 SQL。即使有数十个面向对象 (OO) 程序员参与该项目,也很少有 OO 程序员具有很强的 SQL 技能。假设 SQL 专家甚至不是一个熟悉的 OO 程序员。软件架构师可以决定将所有 SQL 语句分组到一个类 RDBOperations 中,以便 SQL 专家可以轻松地在一个位置处理 SQL。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  One case is the grouping of responsibilities or code into one class or component to simplify maintenance by one personalthough be warned that such grouping may also worsen maintenance. But suppose an application contains embedded SQL statements that by other good design principles should be distributed across ten classes, such as ten "database mapper" classes. Now, commonly only one or two SQL experts know how to best define and maintain this SQL. Even if dozens of object-oriented (OO) programmers work on the project, few OO programmers may have strong SQL skills. Suppose the SQL expert is not even a comfortable OO programmer. The software architect may decide to group all the SQL statements into one class, RDBOperations, so that it is easy for the SQL expert to work on the SQL in one location.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  内聚程度较低的组件的另一种情况是使用分布式服务器对象。由于与远程对象和远程通信相关的开销和性能影响,有时需要创建更少、更大、内聚性更差的服务器对象,以便为许多操作提供接口。此方法还与称为 Coarse-Grained Remote Interface 的模式有关。在这种模式中,远程操作变得更加粗粒度,以便它们可以在远程操作调用中执行或请求更多工作,以减轻通过网络进行远程调用的性能损失。举个简单的例子,有一个远程操作 setData,它接收一组数据,而不是具有三个细粒度操作 setName、setSalarysetHireDate 的远程对象。这样可以减少远程调用并提高性能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Another case for components with lower cohesion is with distributed server objects. Because of overhead and performance implications associated with remote objects and remote communication, it is sometimes desirable to create fewer and larger, less cohesive server objects that provide an interface for many operations. This approach is also related to the pattern called Coarse-Grained Remote Interface. In that pattern the remote operations are made more coarse-grained so that they can to do or request more work in remote operation calls to alleviate the performance penalty of remote calls over a network. As a simple example, instead of a remote object with three fine-grained operations setName, setSalary, and setHireDate, there is one remote operation, setData, which receives a set of data. This results in fewer remote calls and better performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 提高了设计的清晰度和易理解性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Clarity and ease of comprehension of the design is increased.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 简化了维护和增强功能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Maintenance and enhancements are simplified.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 通常支持低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Low coupling is often supported.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 细粒度、高度相关的功能的重用率增加,因为内聚类可用于非常特定的目的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Reuse of fine-grained, highly related functionality is increased because a cohesive class can be used for a very specific purpose.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    17.15. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    17.15. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    RDD 的隐喻尤其体现在波特兰泰克公司 Smalltalk 中具有影响力的对象工作中,该工作来自 Kent Beck、Ward Cunningham、Rebecca Wirfs-Brock 等人。设计面向对象的软件 [WWW90] 是具有里程碑意义的文本,在今天和它编写时一样具有现实意义。Wirfs-Brock 最近发布了另一本 RDD 文本,对象设计:角色、责任和协作 [WM02]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The metaphor of RDD especially emebged from the influential object work in Smalltalk at Tektronix in Portland, from Kent Beck, Ward Cunningham, Rebecca Wirfs-Brock, and others. Designing Object-Oriented Software [WWW90] is the landmark text, and is as relevant today as when it was written. Wirfs-Brock has more recently released another RDD text, Object Design: Roles, Responsibilities, and Collaborations [WM02].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    另外两本强调基本对象设计原则的推荐文本是 Riel 的 Object-Oriented Design Heuristics 和 Coad 的 Object Models

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Two other recommended texts emphasizing fundamental object design principles are Object-Oriented Design Heuristics by Riel and Object Models by Coad.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第 18 章.使用 GRASP 的对象设计示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chapter 18. Object Design Examples with GRASP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      要发明,你需要良好的想象力和一堆垃圾。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      爱迪生

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To invent, you need a good imagination and a pile of junk.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thomas Edison

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 设计用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Design use case realizations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 应用 GRASP 为类分配职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Apply GRASP to assign responsibilities to classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 应用 UML 来说明和思考对象的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Apply UML to illustrate and think through the design of objects.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本章将 OO 设计原则和 UML 应用于案例研究,以展示具有职责和协作的合理设计对象的更大示例。请注意,按名称划分的 GRASP 模式并不重要;它们只是一个学习辅助工具,帮助我们有条不紊地思考基本的 OO 设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This chapter applies OO design principles and the UML to the case studies, to show larger examples of reasonably designed objects with responsibilities and collaborations. Please note that the GRASP patterns by name are not important; they're just a learning aid that helps us think methodically about basic OO design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Key Point

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        职责分配和协作设计是设计过程中非常重要且富有创意的步骤,无论是在绘制图表还是编码时。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The assignment of responsibilities and design of collaborations are very important and creative steps during design, both while diagraming and while coding.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        无魔法区

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The No-Magic Zone

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本章邀请您通过详细的解释了解 OO 开发人员在根据原则进行设计时如何进行推理。事实上,经过短暂的实践,这些原则变得根深蒂固,一些决策几乎发生在潜意识层面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This chapter invites you to learn through detailed explanations how an OO developer might reason while designing by principles. In fact, over a short time of practice, these principles become ingrained, and some of the decision-making happens almost at a subconscious level.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        首先,我想详尽地说明,在对象设计中不需要“魔法”,不需要不合理的决定,责任分配,合作的选择可以得到合理的解释和学习。OO 软件设计确实可以更科学而不是艺术,尽管有足够的空间来发挥创造力和优雅的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        But first, I wish to exhaustively illustrate that no "magic" is needed in object design, no unjustifiable decisions are necessaryassignment of responsibilities and the choice of collaborations can be rationally explained and learned. OO software design really can be more science than art, though there is plenty of room for creativity and elegant design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          18.1. 什么是用例实现?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          18.1. What is a Use Case Realization?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          关于基本 OO 设计原则的最后一章着眼于设计问题的小片段。相比之下,本章演示了为整个用例场景设计域对象[1] 的更大图景。您将看到更大规模的协作和更复杂的 UML 图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The last chapter on basic OO design principles looked at little fragments of design problems. In contrast, this chapter demonstrates the larger picture of designing the domain objects[1] for an entire use case scenario. You will see larger-scale collaborations and more complex UML diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] 回想一下,正如第 200 页所解释的,案例研究集中在领域层,而不是 UI 或服务层,而这些层仍然很重要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] Recall, as explained on p. 200, that the case studies focus on the domain layer, not the UI or service layers, which are nevertheless important.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          引用,“用例实现描述了如何根据协作对象在设计模型中实现特定用例”[RUP]。更准确地说,设计人员可以描述用例的一个或多个场景的设计;这些中的每一个都称为用例实现(尽管不是标准的,也许更应该称为场景实现)。用例实现是一个 UP 术语,用于提醒我们以用例表示的需求与满足需求的对象设计之间的联系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          To quote, "A use-case realization describes how a particular use case is realized within the Design Model, in terms of collaborating objects" [RUP]. More precisely, a designer can describe the design of one or more scenarios of a use case; each of these is called a use case realization (though non-standard, perhaps better called a scenario realization). Use case realization is a UP term used to remind us of the connection between the requirements expressed as use cases and the object design that satisfies the requirements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          UML 图是说明用例实现的通用语言。正如我们在上一章中所探讨的那样,我们可以在这个用例实现设计工作中应用对象设计的原则和模式,比如 Information Expert 和 Low Coupling。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          UML diagrams are a common language to illustrate use case realizations. And as we explored in the prior chapter, we can apply principles and patterns of object design, such as Information Expert and Low Coupling, during this use case realization design work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          回顾一下,图 18.1 说明了一些 UP 工件之间的关系,强调了 Use Case Model 和 Design Model用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          To review, Figure 18.1 illustrates the relationship between some UP artifacts, emphasizing the Use Case Model and the Design Modeluse case realizations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 18.1.工件关系,强调用例实现。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          一些相关的工件影响点包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Some relevant artifact-influence points include the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 该用例建议了 SSD 中显示的系统操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The use case suggests the system operations that are shown in SSDs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 系统操作成为进入 Controller for domain layer 交互图的起始消息。参见图 18.2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 这是 OOA/D 建模新手经常错过的一个关键点

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 18.2.通信图和系统操作处理。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The system operations become the starting messages entering the Controllers for domain layer interaction diagrams. See Figure 18.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • This is a key point often missed by those new to OOA/D modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Figure 18.2. Communication diagrams and system operation handling.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 域层交互图说明了对象如何交互以完成所需的任务用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Domain layer interaction diagrams illustrate how objects interact to fulfill the required tasksthe use case realization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            18.2. Artifact 注释

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            18.2. Artifact Comments

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SSD、系统操作、交互图和用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SSDs, System Operations, Interaction Diagrams, and Use Case Realizations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在当前的 NextGen POS 迭代中,我们正在考虑在流程销售用例的 SSD 上确定的场景和系统操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the current NextGen POS iteration we are considering scenarios and system operations identified on the SSDs of the Process Sale use case:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeNewSale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeNewSale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • enter项目

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • enterItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 结束销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • endSale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makePayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makePayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如果我们使用通信图来说明用例实现,我们将绘制一个不同的通信图来显示每个系统操作消息的处理。当然,序列图也是如此。例如,参见图 18.2图 18.3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            If we use communication diagrams to illustrate the use case realizations, we will draw a different communication diagram to show the handling of each system operation message. Of course, the same is true for sequence diagrams. For example, see Figure 18.2 and Figure 18.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 18.3.序列图和系统操作处理。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Key Point

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SSD 中的系统操作用作域控制器层控制器对象的起始消息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The system operations in the SSDs are used as the starting messages into the domain layer controller objects.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用案例和用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use Cases and Use Case Realizations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            自然,用例是用例实现的主要输入。补充规范、词汇表、UI 原型、报告原型等中表达的用例文本和相关要求都告知开发人员需要构建什么。但请记住,书面要求是不完美的,通常是非常不完美的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Naturally, use cases are a prime input to use case realizations. The use case text and related requirements expressed in the Supplementary Specifications, Glossary, UI prototypes, report prototypes, and so forth, all inform developers what needs to be built. But bear in mind that written requirements are imperfectoften very imperfect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            经常让客户参与进来

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            上一节给人的印象是,文档是进行软件设计和开发的关键需求输入。不过,确实很难击败客户在评估演示、讨论需求和测试、确定优先级等方面的持续参与。敏捷方法的原则之一是“业务人员和开发人员必须在整个项目中每天一起工作”,这是一个非常有价值的目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The above section gives the impression that documents are the critical requirements input to doing software design and development. Truly, though, it is hard to beat the ongoing participation of customers in evaluating demos, discussing requirements and tests, prioritizing, and so forth. One of the principles of agile methods is "Business people and developers must work together daily throughout the project"a very worthy goal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            运营合同和用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Operation Contracts and Use Case Realizations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如前所述,用例实现可以直接从用例文本或个人的领域知识中设计。对于一些复杂的系统操作,可能已经编写了添加更多分析细节的合同。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            As discussed, use case realizations could be designed directly from the use case text or from one's domain knowledge. For some complex system operations, contracts may have been written that add more analysis detail. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            CO2 合同:enterItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            enterItem(itemID : 商品ID, 数量 : 整数)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            enterItem(itemID : ItemID, quantity : integer)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            正在进行促销活动。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            There is a sale underway.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 已创建 SalesLineItem 实例 sli (实例创建)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - ...



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在考虑用例文本的同时,对于每个 Contract,我们都会处理后置条件状态更改并设计消息交互以满足要求。例如,给定这个部分 enterItem 系统操作,我们绘制了一个满足 SalesLineItem 实例创建状态变化的部分交互,如图 18.4 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In conjunction with contemplating the use case text, for each contract, we work through the postcondition state changes and design message interactions to satisfy the requirements. For example, given this partial enterItem system operation, we diagram a partial interaction that satisfies the state change of SalesLineItem instance creation, as shown in Figure 18.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 18.4.部分交互图满足 Contract 后置条件。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            域模型和用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Domain Model and Use Case Realizations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在交互图中,域模型激发了一些软件对象,例如 Sale 概念类和 Sale 软件类。现有的 Domain Modelas 和所有分析工件都不会完美;您应该预料到错误和遗漏。您将发现以前遗漏的新概念,忽略以前确定的概念,并对关联和属性执行同样的操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the interaction diagrams, the Domain Model inspires some of the software objects, such as a Sale conceptual class and Sale software class. The existing Domain Modelas with all analysis artifactswon't be perfect; you should expect errors and omissions. You will discover new concepts that were previously missed, ignore concepts that were previously identified, and do likewise with associations and attributes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            是否必须将 Design Model 中的设计类限制为名称受 Domain Model 启发的类?一点也不。在设计工作中发现在早期域分析中遗漏的新概念类,并组成名称和用途与域模型完全无关的软件类,这是正常的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Must you limit the design classes in the Design Model to classes with names inspired from the Domain Model? Not at all. It's normal to discover new conceptual classes during design work that were missed during earlier domain analysis and to make up software classes whose names and purpose are completely unrelated to the Domain Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              18.3. 下节引言

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              18.3. What's Next?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              本章的其余部分组织如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The remainder of this chapter is organized as follows:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. 对 NextGen POS 的设计进行了比较详细的讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. A relatively detailed discussion of the design of the NextGen POS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              3. 同样,对于垄断案例研究,从第 347 页开始。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              4. Likewise, for the Monopoly case study, starting on p. 347.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              将 UML 和模式应用于这些案例研究,让我们深入了解细节......

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Applying UML and patterns to these case studies, let's get into the details…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                18.4. NextGen 迭代的用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                18.4. Use Case Realizations for the NextGen Iteration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                以下部分探讨了在设计使用基于 GRASP 模式的对象实现的使用案例实现期间所做的选择和决策。我有意详细解释,以表明 OO 设计中没有魔力,它基于合理的原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The following sections explore the choices and decisions made during the design of a use case realization with objects based on the GRASP patterns. I intentionally detail explanations, to show that there's no magic in OO designit's based on justifiable principles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                初始化和“启动”用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Initialization and the 'Start Up' Use Case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Start Up 用例实现是考虑创建大多数 “根” 或长期对象的设计上下文。有关一些设计细节,请参见第 345 页。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Start Up use case realization is the design context in which to consider creating most of the 'root' or long-lived objects. See p. 345 for some of the design details.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                编码时,请先至少对一些 Start Up 初始化进行编程。但是在 OO 设计建模期间,在您发现真正需要创建和初始化的内容之后,最后考虑 Start Up 初始化设计。然后,设计初始化以支持其他用例实现的需求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When coding, program at least some Start Up initialization first. But during OO design modeling, consider the Start Up initialization design last, after you have discovered what really needs to be created and initialized. Then, design the initialization to support the needs of other use case realizations.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                根据此指南,我们将在支持启动设计之前探索流程销售用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Based on this guideline, we will explore the Process Sale use case realization before the supporting Start Up design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何设计 makeNewSale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to Design makeNewSale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makeNewSale 系统操作发生在收银员在客户带着要购买的商品到达后发起开始新销售的请求时。用例可能足以决定什么是必要的,但对于这个案例研究,我们为所有系统操作编写了合同,以演示该方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The makeNewSale system operation occurs when a cashier initiates a request to start a new sale, after a customer has arrived with things to buy. The use case may have been sufficient to decide what was necessary, but for this case study we wrote contracts for all the system operations, to demonstrate the approach.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CO1 合约:makeNewSale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makeNewSale()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makeNewSale()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                没有

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                none

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - 已创建 Sale 实例 (实例创建)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - A Sale instance s was created (instance creation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - s 与 Register 相关联(已形成协会)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - s was associated with the Register (association formed).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - 初始化 s 的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - Attributes of s were initialized.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择 Controller 类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们的第一个设计选择涉及为系统操作消息 enterItem 选择控制器。根据 Controller 模式,以下是一些选择:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Our first design choice involves choosing the controller for the system operation message enterItem. By the Controller pattern, here are some choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                表示整个 “system”、“root object”、专用设备或主要子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Represents the overall "system," "root object," a specialized device, or a major subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Store 的一种根对象,因为我们认为大多数其他域对象都是 Store 的 “inin” 。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Store a kind of root object because we think of most of the other domain objects as "within" the Store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                注册运行软件的专用设备;也称为 POSTerminal

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Register a specialized device that the software runs on; also called a POSTerminal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                POSSystem 一个表示整个系统的名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                POSSystem a name suggesting the overall system

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                表示用例场景的所有系统事件的接收者或处理程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Represents a receiver or handler of all system events of a use case scenario.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleHandler 从模式 <use-case-name> “Handler” 或 “Session” 构造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleHandler constructed from the pattern <use-case-name> "Handler" or "Session"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleSession

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProcessSaleSession



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如果只有几个系统操作,并且 Facade 控制器没有承担太多责任(换句话说,如果它没有变得不连贯),那么选择像 Register 这样的设备对象 Facade Controller 是令人满意的。当我们有许多系统操作,并且我们希望分配责任以保持每个控制器类的轻量级和专注性(换句话说,内聚性)时,选择一个用例控制器是合适的。在这种情况下,Register 就足够了,因为只有几个系统操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Choosing a device-object facade controller like Register is satisfactory if there are only a few system operations and if the facade controller is not taking on too many responsibilities (in other words, if it is not becoming incohesive). Choosing a use case controller is suitable when we have many system operations and we wish to distribute responsibilities in order to keep each controller class lightweight and focused (in other words, cohesive). In this case, Register suffices since there are only a few system operations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请记住,此 Register 是 Design Model 中的软件对象。它不是物理寄存器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Remember, this Register is a software object in the Design Model. It isn't a physical register.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,基于 Controller 模式,图 18.5 中所示的交互图首先向 Register 软件对象发送系统操作 makeNewSale 消息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Thus, based on the Controller pattern, the interaction diagram shown in Figure 18.5 begins by sending the system operation makeNewSale message to a Register software object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.5.应用 GRASP 控制器模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                创建新销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们必须创建一个软件 Sale 对象,而 GRASP Creator 模式建议将创建责任分配给一个类,该类负责聚合、包含或记录要创建的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We must create a software Sale object, and the GRASP Creator pattern suggests assigning the responsibility for creation to a class that aggregates, contains, or records the object to be created.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                分析域模型表明,Register 可以被认为是记录 Sale 的;事实上,数百年来,商业中的“注册”一词一直是指记录(或注册)账户交易(例如销售)的东西。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Analyzing the Domain Model reveals that a Register may be thought of as recording a Sale; indeed, the word "register" in business has for hundreds of years meant the thing that recorded (or registered) account transactions, such as sales.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,Register 是创建 Sale 的合理候选者。请注意这如何支持低表示差距 (LRG)。通过让 Register 创建 Sale,我们可以轻松地随着时间的推移将 Register 与它相关联,以便在会话内的未来操作中,Register 将具有对当前 Sale 实例的引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Thus, Register is a reasonable candidate for creating a Sale. Note how this supports a low representational gap (LRG). And by having the Register create the Sale, we can easily associate the Register with it over time so that during future operations within the session, the Register will have a reference to the current Sale instance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                除了上述内容之外,在创建 Sale 时,它必须创建一个空集合(比如 Java List)来记录将要添加的所有未来 SalesLineItem 实例。此集合将包含在 Sale 实例中并由 Sale 维护,这意味着 Creator 表示 Sale 是创建集合的良好候选项。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In addition to the above, when the Sale is created, it must create an empty collection (such as a Java List) to record all the future SalesLineItem instances that will be added. This collection will be contained within and maintained by the Sale instance, which implies by Creator that the Sale is a good candidate for creating the collection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,Register 创建 Sale,而 Sale 创建一个空集合,由交互图中的多对象表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Therefore, the Register creates the Sale, and the Sale creates an empty collection, represented by a multiobject in the interaction diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,图 18.6 中的交互图说明了该设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Hence, the interaction diagram in Figure 18.6 illustrates the design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.6.Sale 和产品系列创建。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                结论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这个设计并不难,但从控制器和创造者的角度仔细解释的目的是为了说明设计的细节可以理性地、有条不紊地决定,并根据原则和模式(例如 GRASP)进行解释。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The design was not difficult, but the point of its careful explanation in terms of Controller and Creator was to illustrate that the details of a design can be rationally and methodically decided and explained in terms of principles and patterns, such as GRASP.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何设计 enterItem?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to Design enterItem?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当收银员输入 itemID 和(可选)要购买的商品的数量时,将执行 enterItem 系统操作。以下是完整的合同:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The enterItem system operation occurs when a cashier enters the itemID and (optionally) the quantity of something to be purchased. Here is the complete contract:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CO2 合同:enterItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                enterItem(itemID : 商品ID, 数量 : 整数)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                enterItem(itemID : ItemID, quantity : integer)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                正在进行中的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There is an underway sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - 已创建 SalesLineItem 实例 sli (实例创建)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - A SalesLineItem instance sli was created (instance creation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli 与当前销售相关联(已形成关联)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli.quantity 变为 quantity (属性修改)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli.quantity became quantity (attribute modification).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli 根据 itemID 匹配(形成关联)与 ProductDescription 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - sli was associated with a ProductDescription, based on itemID match (association formed).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                现在,我们构建一个交互图来满足 enterItem 的后置条件,使用 GRASP 模式来帮助做出设计决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We now construct an interaction diagram to satisfy the postconditions of enterItem, using the GRASP patterns to help with the design decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择 Controller 类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们的第一个选择涉及处理系统操作消息 enterItem 的责任。根据 Controller 模式,对于 makeNewSale,我们将继续使用 Register 作为 Controller。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Our first choice involves handling the responsibility for the system operation message enterItem. Based on the Controller pattern, as for makeNewSale, we will continue to use Register as a controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                显示商品描述和价格?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由于 Model-View 分离的原则,非 GUI 对象(例如 RegisterSale)不负责参与输出任务。因此,尽管用例指出在此操作后会显示 description 和 price,但我们此时忽略了 design。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Because of a principle of Model-View Separation, it is not the responsibility of non-GUI objects (such as a Register or Sale) to get involved in output tasks. Therefore, although the use case states that the description and price are displayed after this operation, we ignore the design at this time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                关于信息显示的责任,所要求的只是信息是已知的,在这种情况下就是如此。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                All that is required with respect to responsibilities for the display of information is that the information is known, which it is in this case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                创建新的 SalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                enterItem 协定后置条件指示 SalesLineItem 的创建、初始化和关联。对 Domain Model 的分析表明,Sale 包含 SalesLineItem 对象。从域中汲取灵感,我们确定软件 Sale 可能同样包含软件 SalesLineItem。因此,根据 Creator,软件 Sale 是创建 SalesLineItem 的合适候选项。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The enterItem contract postconditions indicate the creation, initialization, and association of a SalesLineItem. Analysis of the Domain Model reveals that a Sale contains SalesLineItem objects. Taking inspiration from the domain, we determine that a software Sale may similarly contain software SalesLineItem. Hence, by Creator, a software Sale is an appropriate candidate to create a SalesLineItem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们可以通过将新实例存储在其行项目集合中,将 Sale 与新创建的 SalesLineItem 关联起来。后置条件指示新的 SalesLineItem 在创建时需要数量;因此,Register 必须将其传递给 Sale,后者必须将其作为 create 消息中的参数传递。在 Java 中,这将实现为带有参数的构造函数调用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We can associate the Sale with the newly created SalesLineItem by storing the new instance in its collection of line items. The postconditions indicate that the new SalesLineItem needs a quantity when created; therefore, the Register must pass it along to the Sale, which must pass it along as a parameter in the create message. In Java, that would be implemented as a constructor call with a parameter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,Creator 会将 makeLineItem 消息发送到 Sale,以便其创建 SalesLineItemSale 将创建一个 SalesLineItem,然后将新实例存储在其永久集合中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Therefore, by Creator, a makeLineItem message is sent to a Sale for it to create a SalesLineItem. The Sale creates a SalesLineItem, and then stores the new instance in its permanent collection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makeLineItem 消息的参数包括数量(以便 SalesLineItem 可以记录数量)以及与 itemID 匹配的 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The parameters to the makeLineItem message include the quantity, so that the SalesLineItem can record it, and the ProductDescription that matches the itemID.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                查找 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SalesLineItem 需要与与传入 itemID 匹配的 ProductDescription 相关联。这意味着我们必须根据 itemID 匹配检索 Product-Description

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The SalesLineItem needs to be associated with the ProductDescription that matches the incoming itemID. This implies that we must retrieve a Product-Description, based on an itemID match.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在考虑如何实现查找之前,我们要考虑应该负责它。因此,第一步是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Before considering how to achieve the lookup, we want to consider who should be responsible for it. Thus, a first step is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                通过明确说明责任来开始分配职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Start assigning responsibilities by clearly stating the responsibility.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                重申问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To restate the problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁应该负责根据 itemID 匹配来了解 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who should be responsible for knowing a ProductDescription, based on an itemID match?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这既不是创建问题,也不是为系统事件选择控制器的问题。现在,我们在设计中看到了 Information Expert 的第一个应用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This is neither a creation problem nor one of choosing a controller for a system event. Now we see our first application of Information Expert in the design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在许多情况下,Expert 模式是要应用的主要模式。Information Expert 建议具有履行责任所需信息的对象应该执行此操作。谁知道所有 ProductDescription 对象?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In many cases, the Expert pattern is the principal one to apply. Information Expert suggests that the object that has the information required to fulfill the responsibility should do it. Who knows about all the ProductDescription objects?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                分析域模型会发现 ProductCatalog 在逻辑上包含所有 ProductDescriptions。再一次,从该领域汲取灵感,我们设计了具有类似组织的软件类:软件 ProductCatalog 将包含软件 ProductDescriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Analyzing the Domain Model reveals that the ProductCatalog logically contains all the ProductDescriptions. Once again, taking inspiration from the domain, we design software classes with similar organization: a software ProductCatalog will contain software ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                确定后,由 Information Expert ProductCatalog 成为此查找职责的不错候选者,因为它知道所有 ProductDescription 对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                With that decided, then by Information Expert ProductCatalog is a good candidate for this lookup responsibility since it knows all the ProductDescription objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如,可以使用名为 getProductDescription(在某些图中缩写为 getProductDesc)的方法实现查找。[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The lookup can be implemented, for example, with a method called getProductDescription (abbreviated as getProductDesc in some of the diagrams).[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [2] 访问方法的名称对每种语言都是惯用的。Java 始终使用 object.getFoo() 形式;C++ 倾向于使用 object.foo();C# 使用 object。Foo,它隐藏(如 Eiffel 和 Ada)访问是通过方法调用还是直接访问 public 属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [2] The name of access methods is idiomatic to each language. Java always uses the object.getFoo() form; C++ tends to use object.foo(); and C# uses object.Foo, which hides (like Eiffel and Ada) whether access is by a method call or is direct access of a public attribute.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProductCatalog 的可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁应该将 getProductDescription 消息发送到 ProductCatalog 以请求 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who should send the getProductDescription message to the ProductCatalog to ask for a ProductDescription?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                可以合理地假设在初始启动使用案例期间创建了长寿命 RegisterProductCatalog 实例,并且 Register 对象永久连接到 ProductCatalog 对象。有了这个假设(当我们开始设计初始化时,我们可能会将其记录在设计中要确保的事项的任务列表中),我们知道 Register 可以将 getProductDescription 消息发送到 ProductCatalog。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                It is reasonable to assume that a long-life Register and a ProductCatalog instance were created during the initial Start Up use case and that the Register object is permanently connected to the ProductCatalog object. With that assumption (which we might record on a task list of things to ensure in the design when we get to designing the initialization), we know that the Register can send the getProductDescription message to the ProductCatalog.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这意味着对象设计中的另一个概念:可见性。可见性是一个对象“看到”或引用另一个对象的能力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This implies another concept in object design: visibility. Visibility is the ability of one object to "see" or have a reference to another object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                要使一个对象向另一个对象发送消息,它必须具有对该对象的可见性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For an object to send a message to another object, it must have visibility to it.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由于我们假设 Register 具有对 ProductCatalog 的永久连接或引用,因此它对它可见,因此可以向其发送诸如 getProductDescription 之类的消息。下一章将更详细地探讨可见性问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Since we assume that the Register has a permanent connectionor referenceto the ProductCatalog, it has visibility to it, and hence can send it messages such as getProductDescription. A following chapter explores the question of visibility more closely.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                最终设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                鉴于上述讨论,图 18.7 中的交互图和图 18.8 中的 DCD(动态和静态视图)反映了有关职责分配和对象应该如何交互的决策。标记对 GRASP 模式的大量反思,它使我们想到了这个设计;对象交互和责任分配的设计需要一些深思熟虑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Given the above discussion, the interaction diagram in Figure 18.7 and the DCD in Figure 18.8 (dynamic and static views) reflects the decisions regarding the assignment of responsibilities and how objects should interact. Mark the considerable reflection on the GRASP patterns, that brought us to this design; the design of object interactions and responsibility assignment requires some deliberation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.7.enterItem 交互图。动态视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.8.与 enterItem 设计相关的部分 DCD。静态视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                然而,一旦这些原则被深深地“掌握”,决定往往很快就会出现,几乎是潜意识的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Yet, once these principles are deeply "grasped" the decisions often come quickly, almost subconsciously.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                从数据库中检索 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 NextGen POS 应用程序的最终版本中,所有 ProductDescription 都不太可能位于内存中。它们很可能会存储在关系数据库中并按需检索;出于性能或容错原因,有些可能在本地缓存。但是,为了简单起见,我们现在推迟了与从数据库检索有关的问题,并假设所有 ProductDescription 都在内存中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the final version of the NextGen POS application, it is unlikely that all the ProductDescriptions will be in memory. They will most likely be stored in a relational database and retrieved on demand; some may be locally cached for performance or fault-tolerance reasons. However, in the interest of simplicity, we defer for now the issues surrounding retrieval from a database and assume that all the ProductDescriptions are in memory.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                第 38 章探讨了持久对象的数据库访问主题,这是一个更大的主题,受技术选择(如 Java 或 .NET)的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Chapter 38 explores the topic of database access of persistent objects, which is a larger topic influenced by the choice of technologies, such as Java or .NET.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何设计 endSale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to Design endSale?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当收银员按下一个按钮,指示将行项目输入到销售中时,将发生 endSale 系统操作(另一个名称可能是 endItemEntry)。这是合同:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The endSale system operation occurs when a cashier presses a button indicating the end of entering line items into a sale (another name could have been endItemEntry). Here is the contract:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CO3 合同:endSale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                endSale()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                endSale()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                正在进行中的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There is an underway sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Sale.isComplete 变为 true(属性修改)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Sale.isComplete became true (attribute modification).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择 Controller 类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们的第一个选择涉及处理系统操作消息 endSale 的责任。根据 Controller GRASP 模式,对于 enterItem,我们将继续使用 Register 作为控制器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Our first choice involves handling the responsibility for the system operation message endSale. Based on the Controller GRASP pattern, as for enterItem, we will continue to use Register as a controller.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                设置 Sale.isComplete 属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                合约后置条件声明:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The contract postconditions state:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Sale.isComplete 变为 true(属性修改)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Sale.isComplete became true (attribute modification).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                与往常一样,Expert 应该是第一个考虑的模式,除非问题是控制器或创建问题(不是)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As always, Expert should be the first pattern considered unless the problem is a controller or creation problem (which it is not).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁应该负责将 SaleisComplete 属性设置为 true?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who should be responsible for setting the isComplete attribute of the Sale to true?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                根据 Expert,它应该是 Sale 本身,因为它拥有并维护 isComplete 属性。因此,Register 将向 Sale 发送一个 becomeComplete 消息以将其设置为 true(参见图 18.9)。[3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                By Expert, it should be the Sale itself, since it owns and maintains the isComplete attribute. Thus, the Register will send a becomeComplete message to the Sale to set it to true (see Figure 18.9).[3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [3]这种风格尤其是 Smalltalk 的惯用语。可能在 Java 中,setComplete(true)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [3] That style is especially a Smalltalk idiom. Probably in Java, setComplete(true).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.9.完成项目输入。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                计算销售总额

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请考虑 Process Sale 用例的以下片段:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Consider this fragment of the Process Sale use case:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 客户到达 ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. Customer arrives ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. Cashier 告诉 System 创建一个新的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. Cashier tells System to create a new sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5. 收银员输入商品标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                6. Cashier enters item identifier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                7. 系统记录销售行项目和...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                8. System records sale line item and ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                收银员重复步骤 3-4,直到指示完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cashier repeats steps 3-4 until indicates done.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 系统显示计算税款的总额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. System presents total with taxes calculated.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在步骤 5 中,显示 (或显示) 总计。由于模型-视图分离原则,我们不应该关心销售总额如何显示的设计,但我们必须确保总数是已知的。请注意,目前没有设计类知道销售总额,因此我们需要创建一个满足此要求的对象交互设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In step 5, a total is presented (or displayed). Because of the Model-View Separation principle, we should not concern ourselves with the design of how the sale total will be displayed, but we must ensure that the total is known. Note that no design class currently knows the sale total, so we need to create a design of object interactions that satisfies this requirement.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                与往常一样,Information Expert 应该是一个可以考虑的模式,除非问题是控制器或创建问题(它不是)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As always, Information Expert should be a pattern to consider unless the problem is a controller or creation problem (which it is not).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                您可能已经通过 Expert 发现 Sale 本身应该负责了解其总数。但是,要清楚地说明寻找 Expert 的推理过程,请遵循对这个简单示例的分析。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                You have probably figured out by Expert that the Sale itself should be responsible for knowing its total. But to make crystal clear the reasoning process to find an Expert, follow the analysis of this simple example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 陈述责任:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 谁应该负责了解销售总额?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. State the responsibility:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Who should be responsible for knowing the sale total?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. 总结所需信息:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 销售总额是所有销售行项目的小计之和。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 销售行项目小计 := 行项目数量 * 产品描述 价格

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. Summarize the information required:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • The sale total is the sum of the subtotals of all the sales line-items.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • sales line-item subtotal := line-item quantity * product description price

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5. 列出履行此职责所需的信息以及知道此信息的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                6. List the information required to fulfill this responsibility and the classes that know this information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                销售总额所需信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Information Required for Sale Total

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                产品描述.price

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProductDescription.price

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                产品描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SalesLineItem.quantity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SalesLineItem.quantity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SalesLineItem 销售行项目

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当前 Sale 中的所有 SalesLineItems

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                all the SalesLineItems in the current Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Sale



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                接下来我们更详细地分析推理过程:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Next we analyze the reasoning process in more detail:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 谁应该负责计算销售总额?通过 Expert,它应该是 Sale 本身,因为它知道所有 SalesLineItem 实例,这些实例必须对小计求和才能计算销售总额。因此,Sale 将负责了解其 total,作为 getTotal 方法实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Who should be responsible for calculating the Sale total? By Expert, it should be the Sale itself, since it knows about all the SalesLineItem instances whose subtotals must be summed to calculate the sale total. Therefore, Sale will have the responsibility of knowing its total, implemented as a getTotal method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 要使 Sale 计算其总计,它需要每个 SalesLineItem 的小计。谁应该负责计算 SalesLineItem 小计?根据 Expert,它应该是 SalesLineItem 本身,因为它知道数量和与之关联的 ProductDescription。因此,SalesLineItem 将负责了解其小计,作为 getSubtotal 方法实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • For a Sale to calculate its total, it needs the subtotal for each SalesLineItem. Who should be responsible for calculating the SalesLineItem subtotal? By Expert, it should be the SalesLineItem itself, since it knows the quantity and the ProductDescription it is associated with. Therefore, SalesLineItem will have the responsibility of knowing its subtotal, implemented as a getSubtotal method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 要使 SalesLineItem 计算其小计,它需要 ProductDescription 的价格。谁应该负责提供 ProductDescription 价格?By Expert 应该是 ProductDescription 本身,因为它将价格封装为属性。因此,ProductDescription 将负责了解其价格,作为 getPrice 操作实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • For the SalesLineItem to calculate its subtotal, it needs the price of the ProductDescription. Who should be responsible for providing the ProductDescription price? By Expert, it should be the ProductDescription itself, since it encapsulates the price as an attribute. Therefore, ProductDescription will have the responsibility of knowing its price, implemented as a getPrice operation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                天哪,这很详细!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                My goodness, that was detailed!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                尽管上述分析在这种情况下是微不足道的,并且在实际设计实践中不需要所呈现的令人痛苦的阐述程度,但寻找专家的相同推理策略可以而且应该应用于更困难的情况。如果您遵循上述逻辑,您就可以看到如何将 Expert 应用于几乎所有问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Although the above analysis is trivial in this case and the degree of excruciating elaboration presented is uncalled for in actual design practice, the same reasoning strategy to find an Expert can and should be applied in more difficult situations. If you follow the above logic, you can see how to apply Expert to almost any problem.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Sale.getTotal 设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                鉴于上述讨论,让我们构建一个交互图,以说明当向 Sale 发送 getTotal 消息时会发生什么。此图中的第一条消息是 getTotal,但请注意,getTotal 消息不是系统操作消息(如 enterItemmakeNewSale)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Given the above discussion, let us construct an interaction diagram that illustrates what happens when a Sale is sent a getTotal message. The first message in this diagram is getTotal, but observe that the getTotal message is not a system operation message (such as enterItem or makeNewSale).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这导致了以下观察结果:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This leads to the following observation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                并非所有交互图都以系统操作消息开头;他们可以从设计者希望显示交互的任何消息开始。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Not all interaction diagrams start with a system operation message; they can start with any message for which the designer wishes to show interactions.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                交互图如图 18.10 所示。首先,将 getTotal 消息发送到 Sale 实例。然后,SalegetSubtotal 消息发送到每个相关的 SalesLineItem 实例。SalesLineItem 反过来将 getPrice 消息发送到其关联的 ProductDescriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The interaction diagram is shown in Figure 18.10. First, the getTotal message is sent to a Sale instance. The Sale then sends a getSubtotal message to each related SalesLineItem instance. The SalesLineItem in turn sends a getPrice message to its associated ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.10.Sale.getTotal 交互图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由于算术(通常)不通过消息来说明,因此我们可以通过将算法或约束附加到定义计算的图来说明计算的细节。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Since arithmetic is not (usually) illustrated via messages, we can illustrate the details of the calculations by attaching algorithms or constraints to the diagram that defines the calculations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁将向 Sale 发送 getTotal 消息?它很可能是 UI 层中的一个对象,比如 Java JFrame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who will send the getTotal message to the Sale? Most likely, it will be an object in the UI layer, such as a Java JFrame.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.12 中观察 UML 2 中 “method” 音符符号样式的使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Observe in Figure 18.12 the use of the "method" note symbol style in UML 2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.12.在 note symbol 中显示方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.11.在 note symbol 中显示方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何设计 makePayment?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to Design makePayment?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makePayment 系统操作在出纳输入要付款的现金金额时发生。以下是完整的合同:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The makePayment system operation occurs when a cashier enters the amount of cash tendered for payment. Here is the complete contract:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CO4 合同:makePayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makePayment( 金额 : 钱 )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                makePayment( amount: Money )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                正在进行中的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There is an underway sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - 创建了一个 Payment 实例 p(实例创建)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - A Payment instance p was created (instance creation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - p.amountTendered 变为 amount (属性修改)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - p.amountTendered became amount (attribute modification).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - p 与当前销售相关联(已形成关联)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - p was associated with the current Sale (association formed).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - 当前销售与品牌旗舰店关联(已形成关联);(将其添加到已完成销售的历史日志中)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                - The current Sale was associated with the Store (association formed); (to add it to the historical log of completed sales).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                我们构造一个设计来满足 makePayment 的后置条件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We construct a design to satisfy the postconditions of makePayment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                创建付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                合约后条件之一规定:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                One of the contract postconditions states:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 已创建一个 Payment 实例 p(实例创建)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A Payment instance p was created (instance creation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这是一项创建责任,因此我们考虑 Creator GRASP 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This is a creation responsibility, so we consider the Creator GRASP pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁记录、汇总、最密切地使用或包含 Payment?说 register 在逻辑上记录 Payment 是有一定吸引力的,因为在实际域中,“register”记录账户信息;这促使 Register 成为候选人,目标是缩小软件设计中的代表性差距。此外,我们可以合理预期 Sale 软件将密切使用付款;因此,它也可能是一个候选者。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who records, aggregates, most closely uses, or contains a Payment? There is some appeal in stating that a Register logically records a Payment because in the real domain a "register" records account information; this motivates Register's candidacy by the goal of reducing the representational gap in the software design. Additionally, we can reasonably expect that Sale software will closely use a Payment; thus, it, too, may be a candidate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                寻找创建者的另一种方法是使用 Expert 模式,即谁是 Information Expert 在初始化数据方面,在本例中为 tender amount。Register 是接收系统操作 makePayment 消息的控制器,因此它最初将具有支付的金额。因此,Register 再次成为候选者。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Another way to find a creator is to use the Expert pattern in terms of who the Information Expert is with respect to initializing datathe amount tendered in this case. The Register is the controller that receives the system operation makePayment message, so it will initially have the amount tendered. Consequently the Register is again a candidate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                总之,有两个候选者:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In summary, there are two candidates:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 注册

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Register

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                现在,这引出了一个关键的设计思路:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Now, this leads to a key design idea:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当有替代设计选择时,请仔细研究替代方案的内聚耦合影响,并可能了解替代方案的未来发展压力。选择具有良好内聚力、耦合性和稳定性的备选方案,以应对未来可能的变化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When there are alternative design choices, take a closer look at the cohesion and coupling implications of the alternatives, and possibly at the future evolution pressures on the alternatives. Choose an alternative with good cohesion, coupling, and stability in the presence of likely future changes.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                考虑这些选择在高内聚和低耦合 GRASP 模式方面的一些含义。如果我们选择 Sale 来创建 Payment,则 Register 的工作(或职责)会更轻松,从而导致更简单的 Register 定义。此外,Register 不需要知道 Payment 实例的存在,因为它可以通过 Sale间接记录,从而导致 Register 中的耦合较低。这导致了图 18.13 所示的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Consider some of the implications of these choices in terms of the High Cohesion and Low Coupling GRASP patterns. If we choose the Sale to create the Payment, the work (or responsibilities) of the Register is lighterleading to a simpler Register definition. Also, the Register does not need to know about the existence of a Payment instance because it can be recorded indirectly via the Saleleading to lower coupling in the Register. This leads to the design shown in Figure 18.13.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.13.Register.makePayment 交互图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                此交互图满足 Contract 的后置条件: Payment 已创建,与 Sale 关联,并且其 amountTendered 已设置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This interaction diagram satisfies the postconditions of the contract: the Payment has been created, associated with the Sale, and its amountTendered has been set.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                记录销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                完成后,要求规定应将销售记录在历史日志中。与往常一样,Information Expert 应该是一个早期的模式,除非问题是控制器或创建问题(不是),并且应该说明责任:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once complete, the requirements state that the sale should be placed in an historical log. As always, Information Expert should be an early pattern considered unless the problem is a controller or creation problem (which it is not), and the responsibility should be stated:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁负责了解所有记录的销售并进行记录?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who is responsible for knowing all the logged sales and doing the logging?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                通过软件设计中低代表性差距的目标(与我们的领域概念相关),我们可以合理地期望 Store 知道所有记录的销售,因为它们与其财务密切相关。其他替代方法包括经典会计概念,如 SalesLedger。随着设计的增长和 Store 变得不连贯,使用 SalesLedger 对象是有意义的(参见图 18.14)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                By the goal of low representational gap in the software design (in relation to our concepts of the domain), we can reasonably expect a Store to know all the logged sales since they are strongly related to its finances. Other alternatives include classic accounting concepts, such as a SalesLedger. Using a SalesLedger object makes sense as the design grows and the Store becomes incohesive (see Figure 18.14).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.14.谁应该负责了解已完成的销售情况?



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                另请注意,合同的后附条件表明了商店的销售相关。这是一个后置条件不是我们想要在设计中实际实现的一个例子。也许我们之前没有考虑过 SalesLedger,但现在我们有了,我们选择使用它而不是 Store。如果是这种情况,我们(理想情况下)也会将 SalesLedger 添加到域模型中,因为销售账本是现实世界域中的一个概念。在设计工作期间,这种发现和变化是意料之中的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Note also that the postconditions of the contract indicate relating the Sale to the Store. This is an example of postconditions not being what we want to actually achieve in the design. Perhaps we didn't think of a SalesLedger earlier, but now that we have, we choose to use it instead of a Store. If this were the case, we would (ideally) add SalesLedger to the Domain Model as well since a sales ledger is a concept in the real-world domain. This kind of discovery and change during design work is to be expected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在这种情况下,我们坚持使用 Store 的最初计划(参见图 18.15)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In this case, we stick with the original plan of using the Store (see Figure 18.15).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.15.记录已完成的销售。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                计算余额

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                的 Process Sale 用例意味着付款的到期余额将打印在收据上,并以某种方式显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Process Sale use case implies that the balance due from a payment be printed on a receipt and displayed somehow.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由于模型-视图分离原则,我们不应该关心天平将如何显示或打印,但我们必须确保它是已知的。请注意,目前没有类知道平衡,因此我们需要创建一个满足此要求的对象交互设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Because of the Model-View Separation principle, we should not concern ourselves with how the balance will be displayed or printed, but we must ensure that it is known. Note that no class currently knows the balance, so we need to create a design of object interactions that satisfies this requirement.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                与往常一样,除非问题是控制器或创建问题(不是),否则应考虑 Information Expert,并且应说明责任:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As always, Information Expert should be considered unless the problem is a controller or creation problem (which it is not), and the responsibility should be stated:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                谁负责了解余额?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Who is responsible for knowing the balance?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                要计算余额,我们需要销售总额和支付现金。因此,SalePayment 是解决此问题的部分专家。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To calculate the balance, we need the sale total and payment cash tendered. Therefore, Sale and Payment are partial Experts on solving this problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如果 Payment 主要负责了解余额,则需要对 Sale 的可见性,以向 Sale 询问其总额。由于它目前不知道 Sale 的情况,这种方法会增加设计中的整体耦合,它不支持 Low Coupling 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If the Payment is primarily responsible for knowing the balance, it needs visibility to the Sale, to ask the Sale for its total. Since it does not currently know about the Sale, this approach would increase the overall coupling in the designit would not support the Low Coupling pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                相反,如果 Sale 主要负责了解余额,则需要对 Payment 的可见性,以要求其提供现金。由于 Sale 已经将 Payment作为其创建者可见,因此这种方法不会增加整体耦合,因此是一种更可取的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In contrast, if the Sale is primarily responsible for knowing the balance, it needs visibility to the Payment, to ask it for its cash tendered. Since the Sale already has visibility to the Paymentas its creatorthis approach does not increase the overall coupling and is therefore a preferable design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,图 18.16 中的交互图为了解平衡提供了一种解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Consequently, the interaction diagram in Figure 18.16 provides a solution for knowing the balance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.16.Sale.getBalance 交互图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                迭代 1 的最终 NextGen DCD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Final NextGen DCD for Iteration-1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                根据本章的设计决策,图 18.17 说明了领域层新兴设计的静态视图 DCD,反映了迭代 1 中所选场景的 Process Sale 用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In accordance with the design decisions in this chapter, Figure 18.17 illustrates a static-view DCD of the emerging design for the domain layer, reflecting the use case realizations for the chosen scenarios of Process Sale in iteration-1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.17.反映大多数设计决策的更完整的 DCD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当然,我们还有更多的 OO 设计工作,无论是在编码时还是在建模时,都要在其他层中完成,包括 UI 层和服务层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Of course, we still have more OO design workeither while coding or while modelingto do in other layers, include the UI layer and services layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何将 UI 层连接到域层?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to Connect the UI Layer to the Domain Layer?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UI 层中的对象获得对域层中对象的可见性的常见设计包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Common designs by which objects in the UI layer obtain visibility to objects in the domain layer include the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 从应用程序启动方法(例如 Java main 方法)调用的初始值设定项对象(例如 Factory 对象)会同时创建 UI 和域对象,并将域对象传递给 UI。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • An initializer object (for example, a Factory object) called from the application starting method (e.g., the Java main method) creates both a UI and a domain object and passes the domain object to the UI.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • UI 对象从已知源(如负责创建域对象的工厂对象)检索域对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A UI object retrieves the domain object from a well-known source, such as a factory object that is responsible for creating domain objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                一旦 UI 对象连接到 Register 实例(本设计中的 Facade 控制器),它就可以将系统事件消息(例如 enterItemendSale 消息)转发给它(参见图 18.18)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once the UI object has a connection to the Register instance (the facade controller in this design), it can forward system event messages, such as the enterItem and endSale message, to it (see Figure 18.18).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.18.连接 UI 层和域层。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                对于 enterItem 消息,我们希望窗口在每个条目之后显示汇总。设计解决方案包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the case of the enterItem message, we want the window to show the running total after each entry. Design solutions are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • getTotal 方法添加到 Register。UI 将 getTotal 消息发送到 Register,后者将委托给 Sale。这可能具有保持从 UI 到域层的较低耦合的可能优势,UI 只知道 Register 对象。但它开始扩展 Register 对象的接口,使其内聚性降低。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Add a getTotal method to the Register. The UI sends the getTotal message to the Register, which delegates to the Sale. This has the possible advantage of maintaining lower coupling from the UI to the domain layerthe UI only knows of the Register object. But it starts to expand the interface of the Register object, making it less cohesive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • UI 请求对当前 Sale 对象的引用,然后当它需要总数(或与销售相关的任何其他信息)时,它会直接向 Sale 发送消息。此设计增加了从 UI 到域层的耦合。然而,正如我们在低耦合 GRASP 模式讨论中所探讨的那样,更高的耦合本身并不是一个问题;相反,耦合到不稳定的事物是一个真正的问题。假设我们认为 Sale 是一个稳定的对象,它将成为设计不可或缺的一部分,这是合理的。那么,与 Sale 耦合就不是一个大问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A UI asks for a reference to the current Sale object, and then when it requires the total (or any other information related to the sale), it directly sends messages to the Sale. This design increases the coupling from the UI to the domain layer. However, as we explored in the Low Coupling GRASP pattern discussion, higher coupling in and of itself is not a problem; rather, coupling to unstable things is a real problem. Assume we decide the Sale is a stable object that will be an integral part of the designwhich is reasonable. Then, coupling to the Sale is not a major problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如图 18.19 所示,此设计遵循第二种方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As illustrated in Figure 18.19, this design follows the second approach.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.19.连接 UI 层和域层。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                初始化和“启动”用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Initialization and the 'Start Up' Use Case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                何时创建初始化设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                大多数(如果不是全部)系统都有隐式或显式的 Start Up 用例,以及一些与应用程序启动相关的初始系统操作。虽然抽象地说, startUp 系统操作是最早执行的,但要延迟为其开发交互图,直到考虑了所有其他系统操作之后。这种做法可确保发现有关支持后续系统操作交互图所需的初始化活动的信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Most, if not all, systems have either an implicit or explicit Start Up use case and some initial system operation related to the starting up of the application. Although abstractly, a startUp system operation is the earliest one to execute, delay the development of an interaction diagram for it until after all other system operations have been considered. This practice ensures that information has been discovered concerning the initialization activities required to support the later system operation interaction diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                最后执行初始化设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do the initialization design last.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                应用程序如何启动?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Start Up 用例的 startUpinitialize 系统操作抽象地表示启动应用程序时执行的初始化阶段。要了解如何为此操作设计交互图,您必须首先了解可以进行初始化的上下文。应用程序的启动和初始化方式取决于编程语言和操作系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The startUp or initialize system operation of a Start Up use case abstractly represents the initialization phase of execution when an application is launched. To understand how to design an interaction diagram for this operation, you must first understand the contexts in which initialization can occur. How an application starts and initializes depends on the programming language and operating system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在所有情况下,一种常见的设计习惯都是创建一个初始域对象或一组对等初始域对象,这些对象是第一个创建的软件“域”对象。此创建可能在起始 main 方法中显式发生,也可能在从 main 方法调用的 Factory 对象中显式发生。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In all cases, a common design idiom is to create an initial domain object or a set of peer initial domain objects that are the first software "domain" objects created. This creation may happen explicitly in the starting main method or in a Factory object called from the main method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                通常,初始域对象(假设为单数情况)一旦创建,就负责创建其直接子域对象。例如,选择作为初始域对象的 Store 可能负责创建 Register 对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Often, the initial domain object (assuming the singular case), once created, is responsible for the creation of its direct child domain objects. For example, a Store chosen as the initial domain object may be responsible for the creation of a Register object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如,在 Java 应用程序中,main 方法可以创建初始域对象或将工作委托给创建它的 Factory 对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In a Java application, for example, the main method may create the initial domain object or delegate the work to a Factory object that creates it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public class Main
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public static void main( String[] args )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // Store is the initial domain object.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // The Store creates some other domain objects.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Store store = new Store();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Register register = store.getRegister();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ProcessSaleJFrame frame = new ProcessSaleJFrame( register );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public class Main
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public static void main( String[] args )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // Store is the initial domain object.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // The Store creates some other domain objects.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Store store = new Store();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Register register = store.getRegister();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ProcessSaleJFrame frame = new ProcessSaleJFrame( register );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择 Initial Domain Object

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                初始域对象的类应该是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What should the class of the initial domain object be?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                选择位于域对象的包含或聚合层次结构的根处或附近的类作为初始域对象。这可能是一个 Facade 控制器,例如 Register,或者被认为包含所有或大多数其他对象的其他对象,例如 Store。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Choose as an initial domain object a class at or near the root of the containment or aggregation hierarchy of domain objects. This may be a facade controller, such as Register, or some other object considered to contain all or most other objects, such as a Store.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                高内聚和低耦合的考虑因素会影响这些备选方案之间的选择。在此应用程序中,我们选择 Store 作为初始对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                High Cohesion and Low Coupling considerations influence the choice between these alternatives. In this application, we chose the Store as the initial object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Store.create 设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                创建和初始化任务源自先前设计工作的需求,例如处理 enterItem 等的设计。通过反思之前的交互设计,我们确定了以下初始化工作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The tasks of creation and initialization derive from the needs of the prior design work, such as the design for handling enterItem and so on. By reflecting on the prior interaction designs, we identify the following initialization work:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 创建 Store、Register、ProductCatalogProductDescriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Create a Store, Register, ProductCatalog, and ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • ProductCatalogProductDescriptions 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Associate the ProductCatalog with ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • StoreProductCatalog 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Associate Store with ProductCatalog.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • StoreRegister 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Associate Store with Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • RegisterProductCatalog 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Associate Register with ProductCatalog.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.20 显示了设计。我们选择了 Store 来创建 ProductCatalog 并按 Creator 模式注册。同样,我们选择 ProductCatalog 来创建 ProductDescriptions。回想一下,这种创建规范的方法是临时的。在最终设计中,我们将根据需要从数据库中实现它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Figure 18.20 shows the design. We chose the Store to create the ProductCatalog and Register by the Creator pattern. Likewise, we chose ProductCatalog to create the ProductDescriptions. Recall that this approach to creating the specifications is temporary. In the final design, we will materialize them from a database, as needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 18.20.创建初始域对象和后续对象。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                应用 UML: 请注意,所有 ProductDescription 实例的创建及其添加到容器中都发生在重复部分中,由序列号后面的 * 表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Applying UML: Observe that the creation of all the ProductDescription instances and their addition to a container happens in a repeating section, indicated by the * following the sequence numbers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                对实际域进行建模和设计建模之间的一个有趣的差异在于,软件 Store 对象只创建一个 Register 对象。一家真正的商店可能容纳许多真实的收银机或 POS 终端。但是,我们正在考虑软件设计,而不是现实生活。在我们当前的要求中,我们的软件 Store 只需要创建软件 Register 的单个实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                An interesting deviation between modeling the real-world domain and the design is illustrated in the fact that the software Store object only creates one Register object. A real store may house many real registers or POS terminals. However, we are considering a software design, not real life. In our current requirements, our software Store only needs to create a single instance of a software Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Domain Model 和 Design Model 中对象类之间的多重性可能不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Multiplicity between classes of objects in the Domain Model and Design Model may not be the same.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  18.5. Monopoly 迭代的用例实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  18.5. Use Case Realizations for the Monopoly Iteration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  首先,一个教育要点:请不要因为它不是商业应用程序而忽视这个案例研究。逻辑,尤其是在以后的迭代中,变得相当复杂,有丰富的 OO 设计问题需要解决。它说明的核心对象设计原则应用 Information Expert,评估备选方案的耦合和内聚性,这与所有领域的对象设计相关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  First, an education point: Please don't dismiss this case study because it isn't a business application. The logic, especially in later iterations, becomes quite complex, with rich OO design problems to solve. The core object design principles that it illustratesapplying Information Expert, evaluating the coupling and cohesion of alternativesare relevant to object design in all domains.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们正在迭代 1 中为用例 Play Monopoly Game 的场景设计一个简化版本的 Monopoly。它有两个系统操作:initialize(或 startUp)和 playGame。按照我们的指导方针,我们将忽略初始化设计,直到最后一步,首先关注主系统操作,在这种情况下只有 playGame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We are designing a simplified version of Monopoly in iteration-1 for a scenario of the use case Play Monopoly Game. It has two system operations: initialize (or startUp) and playGame. Following our guideline, we will ignore initialization design until the last step and focus first on the main system operationsonly playGame in this case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  迭代 1 要求 第 44 页

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  iteration-1 requirements p. 44



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此外,为了支持低表示差距 (LRG) 的目标,我们再次查看图 18.21,它显示了域模型。我们在设计 Design Model 的 domain layer 时从中寻找灵感。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Also, to support the goal of low representational gap (LRG), we look again at Figure 18.21, which shows the Domain Model. We turn to it for inspiration as we design the domain layer of the Design Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.21.Monopoly 的 Iteration-1 Domain Model。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如何设计 playGame?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  How to Design playGame?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当人类游戏观察者执行某些 UI 手势(例如单击“播放游戏”按钮)以请求游戏作为模拟游戏,而观察者观看输出时,将发生 playGame 系统操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The playGame system operation occurs when the human game observer performs some UI gesture (such as clicking a "play game" button) to request the game to play as a simulation while the observer watches the output.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们没有为这个案例研究编写详细的用例或运营合同,因为大多数人都知道规则;我们的重点是设计问题,而不是需求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We didn't write a detailed use case or an operation contract for this case study, as most people know the rules; our focus is the design issues, not the requirements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  选择 Controller 类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们的第一个设计选择涉及为从 UI 层到域层的系统操作消息 playGame 选择控制器。根据 Controller 模式,以下是一些选择:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Our first design choice involves selecting the controller for the system operation message playGame that comes from the UI layer into the domain layer. By the Controller pattern, here are some choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  表示整个 “system”、“root object”、专用设备或主要子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Represents the overall "system," "root object," a specialized device, or a major subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MonopolyGame 一种根对象:我们认为大多数其他领域对象都“包含在”MonopolyGame 中。在大多数 UML 草图中缩写为 MGame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MonopolyGame a kind of root object: We think of most of the other domain objects as "contained within" the MonopolyGame. Abbreviated MGame in most of the UML sketches.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MonopolyGameSystem:一个暗示整个系统的名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MonopolyGameSystem a name suggesting the overall system

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  表示用例场景的所有系统事件的接收者或处理程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Represents a receiver or handler of all system events of a use case scenario.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PlayMonopolyGameHandler 从模式 <use-case-name> “Handler” 构造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PlayMonopolyGameHandler constructed from the pattern <use-case-name> "Handler"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PlayMonopolyGameSession

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PlayMonopolyGameSession



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如果只有几个系统操作(在这个用例中只有两个),并且如果 Façade 控制器没有承担太多责任(换句话说,如果它没有变得不连贯),那么选择像 MonopolyGame图 18.22 中的 MGame)这样的根对象 Facade 控制器是令人满意的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Choosing a root-object facade controller like MonopolyGame (MGame in Figure 18.22) is satisfactory if there are only a few system operations (there are only two in this use case) and if the facade controller is not taking on too many responsibilities (in other words, if it is not becoming incohesive).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.22.将 Controller 应用于 playGame 系统操作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Game-Loop 算法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在讨论 OO 设计选择之前,我们先考虑一下仿真的基本算法。首先,一些术语:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Before discussing OO design choices, we prepare by considering the basic algorithm of the simulation. First, some terminology:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 转动玩家掷骰子并移动棋子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • turn a player rolling the dice and moving the piece

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 回合内所有玩家轮次

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • round all the players taking one turn

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  现在游戏循环:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Now the game loop:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  for N rounds
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for each Player p
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        p takes a turn
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  for N rounds
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for each Player p
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        p takes a turn
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  回想一下,迭代 1 版本没有获胜者,因此模拟只运行 N 轮。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Recall that the iteration-1 version does not have a winner, so the simulation simply runs for N rounds.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  谁负责控制 Game Loop?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  审查算法:第一个责任是 N 轮的游戏循环控制循环,并为每个玩家玩一个回合。这是一个执行责任,而不是创建或控制器问题,因此自然应该考虑 Expert。申请 Expert 意味着要问:“职责需要什么信息?以下是分析:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Reviewing the algorithm: The first responsibility is game loop controllooping for N rounds and having a turn played for each player. This is a doing responsibility and is not a creation or controller problem, so naturally, Expert should be considered. Applying Expert means asking, "What information is needed for the responsibility?" Here's the analysis:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所需信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Information Needed

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  谁拥有这些信息?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Who Has the Information?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当前轮数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  the current round count

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  目前还没有对象具有它,但根据 LRG,将其分配给 MonopolyGame 对象是合理的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  No object has it yet, but by LRG, assigning this to the MonopolyGame object is justifiable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所有玩家(以便每个玩家都可以在回合中使用)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  all the players (so that each can be used in taking a turn)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  从域模型中汲取灵感,MonopolyGame 是一个很好的候选者。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Taking inspiration from the domain model, MonopolyGame is a good candidate.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  因此,根据 Expert,MonopolyGame 是控制游戏循环和协调每一轮游戏的合理选择。图 18.23 在 UML 中进行了说明。请注意使用私有(内部)playRound 帮助程序方法;它至少实现两个目标:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Therefore, by Expert, MonopolyGame is a justifiable choice to control the game loop and coordinate the playing of each round. Figure 18.23 illustrates in UML. Notice the use of a private (internal) playRound helper method; it accomplishes at least two goals:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 它将 play-single-round logic 分解为 helper 方法;最好将 Cogulive Conduct 块组织成小的单独方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 良好的 OO 方法设计鼓励使用具有单一目的的小方法。这在方法级别支持 High Cohesion。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. It factors the play-single-round logic into a helper method; it is good to organize cohesive chunks of behavior into small separate methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Good OO method design encourages small methods with a single purpose. This supports High Cohesion at the method level.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. playRound 这个名字的灵感来自 domain vocabularythat's desirable,它提高了理解力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. The name playRound is inspired by domain vocabularythat's desirable, it improves comprehension.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.23.游戏循环。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  谁轮到谁?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  回合涉及掷骰子并将棋子移动到由骰子面值的总和指示的方格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Taking a turn involves rolling the dice and moving a piece to the square indicated by the total of the dice face values.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  哪个对象应该负责轮到玩家?这是一种事的责任。同样,专家适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What object should be responsible for taking the turn of a player? This is a doing responsibility. Again, Expert applies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  现在,天真的反应可能是说“一个 Player 对象应该轮到”,因为在现实世界中,人类玩家轮到了一个。然而,这是一个关键点:OO 设计并不是对真实领域如何工作的一对一模拟,尤其是关于人们的行为方式。如果您应用了(错误的)准则“将责任放在分配给人员的软件对象中”,那么,例如在 POS 域中,收银员软件对象几乎可以做所有事情!违反了 High Cohesion 和 Low Coupling。大胖子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Now, a naive reaction might be to say "a Player object should take the turn" because in the real world a human player takes a turn. Howeverand this is a key pointOO designs are not one-to-one simulations of how a real domain works, especially with respect to how people behave. If you applied the (wrong) guideline "put responsibilities in software objects as they are assigned to people" then, for example in the POS domain, a Cashier software object would do almost everything! A violation of High Cohesion and Low Coupling. Big fat objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  相反,对象设计根据 Information Expert(以及许多其他对象)的原则在许多对象之间分配责任。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Rather, object designs distribute responsibilities among many objects by the principle of Information Expert (among many others).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  因此,我们不应该仅仅因为人类玩家轮流就选择 Player 对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Therefore, we should not choose a Player object just because a human player takes a turn.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  然而,正如我们将看到的,Player 被证明是一个不错的选择。但理由将是专家,而不是人类行为方式的灵感。申请 Expert 意味着要问:“职责需要什么信息?以下是分析:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Yet, as we shall see, Player turns out to be a good choice for taking a turn. But the justification will be by Expert, not inspiration from how humans behave. Applying Expert means asking, "What information is needed for the responsibility?" Here's the analysis:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所需信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Information Needed

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  谁拥有这些信息?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Who Has the Information?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  玩家的当前位置(了解移动的起点)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  current location of the player (to know the starting point of a move)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  从域模型中汲取灵感,Piece 知道它的 Square而 Player 知道它的 Piece。因此,Player 软件对象可以通过 LRG 知道其位置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Taking inspiration from the domain model, a Piece knows its Square and a Player knows its Piece. Therefore, a Player software object could know its location by LRG.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  两个 Die 对象(用于滚动它们并计算它们的总数)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  the two Die objects (to roll them and calculate their total)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  从域模型中汲取灵感,MonopolyGame 是一个候选者,因为我们认为骰子是游戏的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Taking inspiration from the domain model, MonopolyGame is a candidate since we think of the dice as being part of the game.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所有方格的方格组织(以便能够移动到正确的新方格)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  all the squaresthe square organization (to be able to move to the correct new square)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  对于 LRG,Board 是一个不错的选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  By LRG, Board is a good candidate.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  现在,这是一个有趣的问题!“take a turn” 责任有三个部分信息专家:Player、MonopolyGameBoard

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Now, this is an interesting problem! There are three partial information experts for the "take a turn" responsibility: Player, MonopolyGame, and Board.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这个问题的有趣之处在于如何解决它OO 开发人员可能会考虑的评估和权衡。这是解决问题的第一个准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What's interesting about this problem is how to resolve itthe evaluations and trade-offs an OO developer may consider. Here's the first guideline to solve the problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 当有多个部分信息专家可供选择时,将责任放在占主导地位的信息专家中,即拥有大部分信息的对象。这往往最能支持 Low Coupling。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: When there are multiple partial information experts to choose from, place the responsibility in the dominant information expertthe object with the majority of the information. This tends to best support Low Coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  不幸的是,在这种情况下,都相当平等,每个都有大约三分之一的信息没有占主导地位的专家。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Unfortunately, in this case, are all rather equal, each with about one-third of the informationno dominant expert.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所以,这是另一个可以尝试的准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  So, here's another guideline to try:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 当有其他设计选择时,请考虑每种设计选择的耦合和内聚影响,然后选择最佳选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: When there are alternative design choices, consider the coupling and cohesion impact of each, and choose the best.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  好的,可以应用。MonopolyGame 已经在做一些工作,因此给它更多的工作会影响它的内聚力,尤其是与 PlayerBoard 对象相比,它们还没有做任何事情。但我们仍然与这些对象有双向联系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  OK, that can be applied. MonopolyGame is already doing some work, so giving it more work impacts its cohesion, especially when contrasted with a Player and Board object, which are not doing anything yet. But we still have a two-way tie with these objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  所以,这是另一个准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  So, here's another guideline:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  指南: 当其他准则的备选方案中没有明显的赢家时,请考虑软件对象未来可能的演变以及 Information Expert、内聚和耦合方面的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Guideline: When there is no clear winner from the alternatives other guidelines, consider probable future evolution of the software objects and the impact in terms of Information Expert, cohesion, and coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  例如,在迭代 1 中,轮次不涉及太多信息。但是,请在以后的迭代中考虑完整的游戏规则集。然后,轮到回合时,如果玩家有足够的钱,或者它的颜色是否符合玩家的「颜色策略」,就可以购买玩家所拥有的属性。什么对象会知道玩家的现金总额?答案:玩家(由 LRG 提供)。哪个对象需要知道玩家的颜色策略?答案:玩家(由 LRG 提供,因为它涉及玩家当前持有的财产)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For example, in iteration-1, taking a turn doesn't involve much information. However, consider the complete set of game rules in a later iteration. Then, taking a turn can involve buying a property that the player lands on, if the player has enough money or if its color fits in with the player's "color strategy." What object would be expected to know a player's cash total? Answer: a Player (by LRG). What object would be expected to know a player's color strategy? Answer: a Player (by LRG, as it involves a player's current holdings of properties).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  因此,最终,根据这些准则,玩家被证明是一个不错的候选人,当我们考虑完整的游戏规则时,Expert 证明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Thus, in the end, by these guidelines Player turns out to be a good candidate, justified by Expert when we consider the full game rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  天哪,这很详细!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  My goodness, that was detailed!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当然,这个讨论比你通常想读的要详细得多!然而,如果你现在能够遵循它的推理并将其应用于新的情况,那么它将在你作为 OO 开发人员的余下职业生涯中为你提供很好的帮助,因此值得付出努力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Surely this discussion was more detailed than you normally want to read! Yet, if you can now follow its reasoning and apply it in new situations, it will serve you very well for the remainder of your career as an OO developer, and thus have been worth the effort.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  基于以上,图 18.24 说明了新兴的动态设计和静态设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Based on the above, Figure 18.24 illustrates the emerging dynamic design and static design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.24.玩家轮到专家。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  应用 UML: 请注意指示将 takeTurn 消息发送到名为 players 的集合中的每个玩家的方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Applying UML: Notice the approach to indicating that the takeTurn message is sent to each player in a collection named players.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  转弯

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  转弯意味着:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Taking a turn means:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 计算 2 到 12 之间的随机数总数(两个骰子的范围)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. calculating a random number total between 2 and 12 (the range of two dice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 计算新的 Square 位置

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. calculating the new square location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 将玩家的棋子从旧位置移动到新的 Square 位置

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. moving the player's piece from an old location to a new square location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  首先,随机数问题:通过 LRG,我们将创建一个具有 faceValue 属性的 Die 对象。计算新的随机 faceValue 涉及更改 Die 中的信息,因此 Expert Die 应该能够“掷出”自身(使用域词汇生成新的随机值),并回答其 faceValue

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  First, the random number problem: By LRG, we'll create a Die object with a faceValue attribute. Calculating a new random faceValue involves changing information in the Die, so by Expert Die should be able to "roll" itself (generate a new random value, using domain vocabulary), and answer its faceValue.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第二,新方格位置问题:根据 LRG,Board 知道其所有方格是合理的。然后,由 Expert 负责了解新的方格位置,给定旧的方格位置和一些偏移量(骰子总数)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Second, the new square location problem: By LRG, it's reasonable that a Board knows all its Squares. Then by Expert a Board will be responsible for knowing a new square location, given an old square location, and some offset (the dice total).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第三,棋子移动问题:通过 LRG,玩家知道它的 T棋子,而棋子知道它的 Square 位置(甚至 Player 直接知道它的 Square 位置)是合理的。然后,由 Expert 将 A Piece 设置其新位置,但它可能会从其所有者 Player(玩家)那里获得新位置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Third, the piece movement problem: By LRG, it's reasonable for a Player to know its Piece, and a Piece its Square location (or even for a Player to directly know its Square location). Then by Expert a Piece will set its new location, but it may receive that new location from its owner, the Player.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  谁来协调这一切?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  以上三个步骤需要通过某个对象进行协调。由于 Player 负责轮次,因此 Player 应该协调。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The above three steps need to be coordinated by some object. Since the Player is responsible for taking a turn, the Player should coordinate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  可见性问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  但是,Player 协调这些步骤意味着它与 Die、BoardPiece 对象协作。这意味着可见性需求 Player 必须具有对这些对象的对象引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  However, that the Player coordinates these steps implies its collaboration with the Die, Board, and Piece objects. And this implies a visibility needthe Player must have an object reference to those objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  由于 Player 每回合都需要对 Die、BoardPiece 对象可见,因此我们可以在启动期间使用对这些对象的永久引用来有效地初始化 Player

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Since the Player will need visibility to the Die, Board, and Piece objects each and every turn, we can usefully initialize the Player during startup with permanent references to those objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  playGame 的最终设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  基于上述设计决策,新兴的动态设计如图 18.25 所示,静态设计如图 18.26 所示。请注意,每条信息、每一项责任分配都是由 GRASP 原则有条不紊地、理性地推动的。当您掌握这些原则时,您将能够通过设计进行推理,并根据耦合、内聚、专家等评估现有原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Based on the above design decisions, the emerging dynamic design is as shown in Figure 18.25 and the static design as in Figure 18.26. Notice that each message, each allocation of responsibility, was methodically and rationally motivated by the GRASP principles. As you come to master these principles, you will be able to reason through a design and evaluate existing ones in terms of coupling, cohesion, Expert, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.25.playGame 的动态设计。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.26.playGame 的静态设计。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  应用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Applying UML:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 请注意,在图 18.25 中,我展示了两个序列图。在顶部,发送给 PlayertakeTurn 消息未展开。然后,在下图中,我展开 takeTurn 消息。这是一种常见的草图绘制样式,因此每个挂图都不会太大。这两个关系图是非正式的。更正式地说,我可以使用 UML sdref 帧(参见第 235 页),这在 UML 工具中既简单又合适;但对于画墙素描来说,非正式就足够了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Notice in Figure 18.25 that I show two sequence diagrams. In the top, the takeTurn message to a Player is not expanded. Then, in the bottom diagram, I expand the takeTurn message. This is a common sketching style, so that each wall diagram is not too large. The two diagrams are related informally. More formally, I could use UML sd and ref frames (see p. 235), which would be easy and appropriate in a UML tool; but for wall sketching, informality suffices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 再次注意,对于对 Die 对象的 rollgetFaceValue 消息,在对集合选择对象的消息周围绘制一个循环框架的约定,以指示集合中每个元素的集合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Notice again, with the roll and getFaceValue messages to a Die object, the convention of drawing a loop frame around messages to a collection selection object, to indicate collection over each element in a collection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 请注意 getSquare 消息中的参数 fvTot。我非正式地建议这是所有 Die faceValues 的总和。当我们应用“UML as sketch”时,这种非正式是合适的,假设观众理解上下文。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Notice the parameter fvTot in the getSquare message. I am informally suggesting this is the total of all the Die faceValues. This kind of informality is appropriate when we apply "UML as sketch," assuming the audience understands the context.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Command-Query 分离原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Command-Query Separation Principle

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,在图 18.25 中,骰子的消息后面跟着第二个 getFaceValue 来检索它的新 faceValue。特别是,roll 方法是 void,它没有返回值。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Notice in Figure 18.25 that the message to roll the Die is followed by a second getFaceValue to retrieve its new faceValue. In particular, the roll method is voidit has no return value. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // style #1; used in the official solution
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void roll()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     faceValue = // random num generation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public int getFaceValue()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // style #1; used in the official solution
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void roll()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     faceValue = // random num generation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public int getFaceValue()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  为什么不让 roll 非 void 并组合这两个函数,以便 roll 方法返回新的 faceValue,如下所示?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Why not make roll non-void and combine these two functions so that the roll method returns the new faceValue, as follows?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // style #2; why is this poor?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public int roll()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     faceValue = // random num generation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // style #2; why is this poor?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public int roll()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     faceValue = // random num generation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  您可以找到许多遵循样式 #2 的代码示例,但它被认为是不可取的,因为它违反了命令-查询分离原则 (CQS),这是方法的经典 OO 设计原则 [Meyer88]。该原则指出,每种方法都应该是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  You can find many examples of code that follow style #2, but it is considered undesirable because it violates the Command-Query Separation Principle, (CQS) a classic OO design principle for methods [Meyer88]. This principle states that every method should either be:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 执行操作 (更新、协调等) 的命令方法通常具有副作用,例如更改对象的状态,并且为 void (无返回值) ;或

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a command method that performs an action (updating, coordinating, …), often has side effects such as changing the state of objects, and is void (no return value); or

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 向调用方返回数据且没有副作用的 Query 不应永久更改任何对象的状态

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a query that returns data to the caller and has no side effectsit should not permanently change the state of any objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  但是,这是关键点一种方法不应该两者兼而有之

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Butand this is the key pointa method should not be both.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  roll 方法是一个 command,它具有改变 Die 的 faceValue 状态的副作用。因此,它不应该也返回新的 faceValue,因为那样该方法也会成为一种查询,并违反 “must be void” 规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The roll method is a commandit has the side effect of changing the state of the Die's faceValue. Therefore, it should not also return the new faceValue, as then the method also becomes a kind of query and violates the "must be void" rule.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  动机:为什么要打扰?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CQS 在计算机科学理论中被广泛认为是可取的,因为有了它,您可以更轻松地推理程序的状态,而无需同时修改该状态。它使设计更易于理解和预测。例如,如果应用程序始终遵循 CQS,则您知道 query 或 getter 方法不会修改任何内容,命令也不会返回任何内容。简单的模式。事实证明,这往往是很好的依赖,因为替代方案可能是一个令人讨厌的惊喜,违反了软件开发中的最小惊喜原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CQS is widely considered desirable in computer science theory because with it, you can more easily reason about a program's state without simultaneously modifying that state. And it makes designs simpler to understand and anticipate. For example, if an application consistently follows CQS, you know that a query or getter method isn't going to modify anything and a command isn't going to return anything. Simple pattern. This often turns out to be nice to rely on, as the alternative can be a nasty surpriseviolating the Principle of Least Surprise in software development.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  考虑这个人为但具有爆炸性的反例,其中查询方法违反了 CQS:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Consider this contrived but explosive counter-example in which a query method violates CQS:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Missile m = new Missile();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // looks harmless to me!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  String name = m.getName();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Missile
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public String getName()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     launch(); // launch missile!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Missile m = new Missile();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // looks harmless to me!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  String name = m.getName();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Missile
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public String getName()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     launch(); // launch missile!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  初始化和“启动”用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Initialization and the 'Start Up' Use Case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  initialize system 操作至少在抽象地发生在 Start Up 用例中。对于此设计,我们必须首先选择一个合适的根对象,该对象将成为其他对象的创建者。例如,MonopolyGame 本身就是一个很好的候选根对象。例如,通过创造者,大富翁游戏可以合理地创建棋盘玩家,例如,棋盘可以合理地创建方块。我们可以使用 UML 交互图来展示动态设计的细节,但我将利用这个案例作为机会,在类图中展示用 “create” 刻板印象的 UML 依赖关系线。图 18.27 说明了一个 static 视图图,它建议了创建逻辑。我忽略了互动的细节。事实上,这可能是合适的,因为从这个 UML 草图中,我们(绘制此草图的开发人员)可以很容易地在编码时弄清楚创建细节。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The initialize system operation occurs, at least abstractly, in a Start Up use case. For this design, we must first choose a suitable root object that will be the creator of some other objects. For example, MonopolyGame is itself a good candidate root object. By Creator, the MonopolyGame can justifiably create the Board and Players, for exampleand the Board can justifiably create the Squares, for example. We could show the details of the dynamic design with UML interaction diagrams, but I'll use this case as an opportunity to show a UML dependency line stereotyped with «create», in a class diagram. Figure 18.27 illustrates a static view diagram that suggests the creation logic. I ignore the fine details of the interactions. In fact, that's probably suitable, because from this UML sketch we (the developers who drew this) can pretty easily figure out the creation details while coding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 18.27.创建依赖项。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    18.6. 过程:迭代和进化对象设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    18.6. Process: Iterative and Evolutionary Object Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在过去的几章中,我为用例实现的迭代和进化对象设计提出了许多建议,包括

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I've made many suggestions about iterative and evolutionary object design for use case realizations over the last few chapters, including

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 213 页上的“On to Object Design”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • "On to Object Design" on page 213

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 272 页上的“对象设计:示例输入、活动和输出”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • "Object Design: Example Inputs, Activities, and Outputs" on page 272

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    要点是:保持简洁明了,快速进行编码和测试,不要试图在 UML 模型中详细说明所有内容。对设计的创意、困难部分进行建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The essential point: Keep it light and short, move quickly to code and test, and don't try to detail everything in UML models. Model the creative, difficult parts of the design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 18.28 提供了有关执行这项工作的时间和空间的建议。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Figure 18.28 offers suggestions on the time and space for doing this work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 18.28.示例流程和设置上下文。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    UP 中的对象设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Object Design Within the UP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    再次将 UP 视为示例迭代方法:用例实现是 UP 设计模型的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To again consider the UP as the example iterative method: use case realizations are part of the UP Design Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    初始设计模型和用例实现通常在细化之前不会开始,因为它们涉及详细的设计决策,而这些决策在开始时还为时过早。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Inception The Design Model and use case realizations will not usually be started until elaboration because they involve detailed design decisions, which are premature during inception.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    阐述在此阶段,可能会为设计的架构上最重要或风险最高的场景创建用例实现。但是,UML 图并非针对每种情况都进行,也不一定完整和细粒度的细节。这个想法是为关键用例实现制作交互图,这些实现受益于一些预见和对替代方案的探索,重点关注主要的设计决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Elaboration During this phase, use case realizations may be created for the most architecturally significant or risky scenarios of the design. However, UML diagramming will not be done for every scenario, and not necessarily in complete and fine-grained detail. The idea is to do interaction diagrams for the key use case realizations that benefit from some forethought and exploration of alternatives, focusing on the major design decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    建设为剩余的设计问题创建用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Construction Use case realizations are created for remaining design problems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    表 18.1 总结道。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Table 18.1 summarizes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    表 18.1.UP 伪影和计时示例。s - 开始;R - 优化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    学科

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discipline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    人工制品

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Artifact

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因塞普。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Incep.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    埃拉布。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Elab.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    常量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Const.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    反式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Trans.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    迭 代

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Iteration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    E1..中文

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    E1..En

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    C1..快递 之 家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    C1..Cn

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    T1..T2 航站楼

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    T1..T2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    业务建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Business Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    要求

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Requirements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    使用案例模型 (SSD)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Use Case Model (SSDs)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    补充规格

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Supplementary Specification

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    词汇表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Glossary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    设计模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Design Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    软件架构文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SW Architecture Document

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    数据模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Data Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      18.7. 小结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      18.7. Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      设计对象交互和分配职责是对象设计的核心。这些选择可能会对对象软件系统的可扩展性、清晰度和可维护性以及可重用组件的程度和质量产生深远影响。有一些原则可以做出责任分配的选择;GRASP 模式总结了面向对象设计人员使用的一些最通用和最常见的模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Designing object interactions and assigning responsibilities is at the heart of object design. These choices can have a profound impact on the extensibility, clarity, and maintainability of an object software system, plus on the degree and quality of reusable components. There are principles by which the choices of responsibility assignment can be made; the GRASP patterns summarize some of the most general and common ones used by object-oriented designers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        第 19 章.为可见性而设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Chapter 19. Designing for Visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        数学家是将咖啡转化为定理的设备。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        保罗·埃尔多斯

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A mathematician is a device for turning coffee into theorems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Paul Erdös

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 确定四种类型的可见性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Identify four kinds of visibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 通过设计建立可见性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Design to establish visibility.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          可见性是一个对象查看或引用另一个对象的能力。本章探讨了这个基本但必要的设计问题;那些刚接触 Object Design 的人有时不会考虑和设计以实现必要的可见性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Visibility is the ability of one object to see or have reference to another. This chapter explores this basic but necessary design issue; those new to object design sometimes don't think about and design to achieve necessary visibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            19.1. 对象之间的可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            19.1. Visibility Between Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            为系统操作 (enterItem 等) 创建的设计说明了对象之间的消息。要使发送方对象向接收方对象发送消息,发送方必须对接收方可见发送方必须具有指向接收方对象的某种引用或指针。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The designs created for the system operations (enterItem, and so on) illustrate messages between objects. For a sender object to send a message to a receiver object, the sender must be visible to the receiverthe sender must have some kind of reference or pointer to the receiver object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,从 Register 发送到 ProductCataloggetProductDescription 消息意味着 ProductCatalog 实例对 Register 实例可见,如图 19.1 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, the getProductDescription message sent from a Register to a ProductCatalog implies that the ProductCatalog instance is visible to the Register instance, as shown in Figure 19.1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 19.1.需要从 Register 到 ProductCatalog 的可见性。[1]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [1] 在本代码示例和后续代码示例中,为了简洁明了,可以进行语言简化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [1] In this and subsequent code examples, language simplifications may be made for the sake of brevity and clarity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在创建交互对象的设计时,必须确保存在必要的可见性以支持消息交互。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            When creating a design of interacting objects, it is necessary to ensure that the necessary visibility is present to support message interaction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              19.2. 什么是可见性?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              19.2. What is Visibility?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在通常的用法中,可见性是对象“看到”或引用另一个对象的能力。更一般地说,它与范围问题有关:一个资源(例如实例)是否在另一个资源的范围内?从对象 A 到对象 B 的可见性有四种常见方法:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In common usage, visibility is the ability of an object to "see" or have a reference to another object. More generally, it is related to the issue of scope: Is one resource (such as an instance) within the scope of another? There are four common ways that visibility can be achieved from object A to object B:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 属性可见性B 是 A 的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Attribute visibility B is an attribute of A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 参数可见性B 是 A 方法的参数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Parameter visibility B is a parameter of a method of A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 本地可见性B 是 A 方法中的(非参数)本地对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Local visibility B is a (non-parameter) local object in a method of A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 全球可见性B 在某种程度上是全球可见的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Global visibility B is in some way globally visible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              考虑可见性的动机是这样的:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The motivation to consider visibility is this:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              要使对象 A 向对象 B 发送消息,对象 B 必须对对象 A 可见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For an object A to send a message to an object B, B must be visible to A.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,要创建一个交互图,在该图中将消息从 Register 实例发送到 ProductCatalog 实例,Register 必须对 ProductCatalog 可见。典型的可见性解决方案是将对 ProductCatalog 实例的引用作为 Register 的一个属性进行维护。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, to create an interaction diagram in which a message is sent from a Register instance to a ProductCatalog instance, the Register must have visibility to the ProductCatalog. A typical visibility solution is that a reference to the ProductCatalog instance is maintained as an attribute of the Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              属性可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Attribute Visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              当 B 是 A 的属性时,存在从 A 到 B 的属性可见性。它是一个相对永久的可见性,因为只要 A 和 B 存在,它就会持续存在。这是面向对象系统中一种非常常见的可见性形式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Attribute visibility from A to B exists when B is an attribute of A. It is a relatively permanent visibility because it persists as long as A and B exist. This is a very common form of visibility in object-oriented systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              为了说明这一点,在 Register 的 Java 类定义中,Register 实例可能具有 ProductCatalog 的属性可见性,因为它是 Register 的一个属性(Java 实例变量)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              To illustrate, in a Java class definition for Register, a Register instance may have attribute visibility to a ProductCatalog, since it is an attribute (Java instance variable) of the Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private ProductCatalog catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private ProductCatalog catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这种可见性是必需的,因为在图 19.2 所示的 enterItem 图中,Register 需要将 getProductDescription 消息发送到 ProductCatalog

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This visibility is required because in the enterItem diagram shown in Figure 19.2, a Register needs to send the getProductDescription message to a ProductCatalog:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 19.2.属性可见性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              参数可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Parameter Visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              当 B 作为参数传递给 A 的方法时,存在从 A 到 B 的参数可见性。这是一个相对临时的可见性,因为它仅在方法范围内持续存在。在面向对象的系统中,它是仅次于属性可见性的第二种最常见的可见性形式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Parameter visibility from A to B exists when B is passed as a parameter to a method of A. It is a relatively temporary visibility because it persists only within the scope of the method. After attribute visibility, it is the second most common form of visibility in object-oriented systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              为了说明这一点,当 makeLineItem 消息发送到 Sale 实例时,ProductDescription 实例将作为参数传递。在 makeLineItem 方法的范围内,Sale 具有对 ProductDescription 的参数可见性(参见图 19.3)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              To illustrate, when the makeLineItem message is sent to a Sale instance, a ProductDescription instance is passed as a parameter. Within the scope of the makeLineItem method, the Sale has parameter visibility to a ProductDescription (see Figure 19.3).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 19.3.参数可见性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              将参数可见性转换为属性可见性是很常见的。当 Sale 创建新的 SalesLineItem 时,它会将 ProductDescription 传递给其初始化方法(在 C++ 或 Java 中,这将是其构造函数)。在初始化方法中,参数被分配给一个属性,从而建立属性可见性(图 19.4)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It is common to transform parameter visibility into attribute visibility. When the Sale creates a new SalesLineItem, it passes the ProductDescription in to its initializing method (in C++ or Java, this would be its constructor). Within the initializing method, the parameter is assigned to an attribute, thus establishing attribute visibility (Figure 19.4).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 19.4.属性 visibility 的参数。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              本地可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Local Visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              当 B 在 A 的方法中被声明为本地对象时,存在从 A 到 B 的本地可见性。这是一个相对临时的可见性,因为它仅在方法范围内持续存在。在面向对象的系统中,它是仅次于参数可见性的第三种最常见的可见性形式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Local visibility from A to B exists when B is declared as a local object within a method of A. It is a relatively temporary visibility because it persists only within the scope of the method. After parameter visibility, it is the third most common form of visibility in object-oriented systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              实现本地可见性的两种常见方法是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Two common means by which local visibility is achieved are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 创建新的本地实例并将其分配给局部变量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Create a new local instance and assign it to a local variable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 将方法调用的返回对象分配给局部变量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Assign the returning object from a method invocation to a local variable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              与参数可见性一样,将本地声明的可见性转换为属性可见性是很常见的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As with parameter visibility, it is common to transform locally declared visibility into attribute visibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              第二种变体的示例(将返回对象分配给局部变量)可以在 Register 类的 enterItem 方法中找到(图 19.5)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              An example of the second variation (assigning the returning object to a local variable) can be found in the enterItem method of class Register (Figure 19.5).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 19.5.本地可见性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              第二种变体的一个微妙版本是,当方法没有显式声明变量,但作为从方法调用返回的对象的结果隐式存在时。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A subtle version on the second variation is when the method does not explicitly declare a variable, but one implicitly exists as the result of a returning object from a method invocation. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // there is implicit local visibility to the foo object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // returned via the getFoo call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              anObject.getFoo().doBar();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // there is implicit local visibility to the foo object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // returned via the getFoo call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              anObject.getFoo().doBar();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              全球可见性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Global Visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              当 B 对 A 是全局可见性时,存在从 A 到 B 的全局可见性。它是一个相对永久的可见性,因为只要 A 和 B 存在,它就会持续存在。它是面向对象的系统中最不常见的可见性形式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Global visibility from A to B exists when B is global to A. It is a relatively permanent visibility because it persists as long as A and B exist. It is the least common form of visibility in object-oriented systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              实现全局可见性的一种方法是将实例分配给全局变量,这在某些语言(如 C++)中是可能的,但在其他语言(如 Java)中则不行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              One way to achieve global visibility is to assign an instance to a global variable, which is possible in some languages, such as C++, but not others, such as Java.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              实现全局可见性的首选方法是使用单例模式 [GHJV95],这将在后面的章节中讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The preferred method to achieve global visibility is to use the Singleton pattern [GHJV95], which is discussed in a later chapter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                第 20 章.将设计映射到代码

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Chapter 20. Mapping Designs to Code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当心上述代码中的错误;我只是证明了它是正确的,而不是尝试过。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                唐纳德·克努斯

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Beware of bugs in the above code; I have only proved it correct, not tried it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Donald Knuth

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 将设计工件映射到面向对象语言中的代码。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Map design artifacts to code in an object-oriented language.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  随着当前案例研究迭代的交互图和 DCD 的完成,有足够的思考和细节来为对象的域层剪切一些代码。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  With the completion of interaction diagrams and DCDs for the current iteration of the case studies, there's more than enough thought and detail to cut some code for the domain layer of objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在设计工作期间创建的 UML 工件交互图和 DCD 将用作代码生成过程的输入。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The UML artifacts created during the design workthe interaction diagrams and DCDswill be used as input to the code generation process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在 UP 术语中,存在一个 Implementation Model。这是所有实现工件,例如源代码、数据库定义、JSP/XML/HTML 页面等。因此,本章中创建的代码可以被视为 UP 实现模型的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In UP terms, there exists an Implementation Model. This is all the implementation artifacts, such as the source code, database definitions, JSP/XML/HTML pages, and so forth. Thus, the code being created in this chapter can be considered part of the UP Implementation Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  语言示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Language Samples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Java 被用于示例,因为它被广泛使用和熟悉。但是,这并不意味着对 Java 的特别认可;C#、Visual Basic、C++、Smalltalk、Python 和许多其他语言都适用于本案例研究中介绍的对象设计原则和代码映射。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Java is used for the examples because of its widespread use and familiarity. However, this is not meant to imply a special endorsement of Java; C#, Visual Basic, C++, Smalltalk, Python, and many more languages are amenable to the object design principles and mapping to code presented in this case study.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    20.1. 编程和迭代、进化开发

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    20.1. Programming and Iterative, Evolutionary Development

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    不应将先前的设计建模视为没有原型设计或边编程边设计;现代开发工具为快速探索和重构替代方法提供了绝佳的环境,并且一些(通常是很多)边编程边设计是值得的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The prior design modeling should not be taken to imply that there is no prototyping or design-while-programming; modern development tools provide an excellent environment to quickly explore and refactor alternate approaches, and some (often lots) design-while-programming is worthwhile.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    使用 OO 语言(如 Java 或 C#)创建代码不是 OOA/Dit 最终目标的一部分。在 Design Model 中创建的工件提供了生成代码所需的一些信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The creation of code in an OO languagesuch as Java or C#is not part of OOA/Dit's an end goal. The artifacts created in the Design Model provide some of the information necessary to generate the code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    用例加上 OOA/D 加上 OO 编程的优势在于,它们提供了从需求到代码的端到端路线图。各种工件以可跟踪且有用的方式馈送到以后的工件中,最终以运行应用程序为高。这并不是说这条路会一帆风顺,或者可以简单地机械地遵循有很多变量。但是,拥有路线图为实验和讨论提供了一个起点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A strength of use cases plus OOA/D plus OO programming is that they provide an end-to-end roadmap from requirements through to code. The various artifacts feed into later artifacts in a traceable and useful manner, ultimately culminating in a running application. This is not to suggest that the road will be smooth, or can simply be mechanically followedthere are many variables. But having a roadmap provides a starting point for experimentation and discussion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    实施过程中的创造力和变化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Creativity and Change During Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在设计工作期间完成了一些决策和创造性工作。在下面的讨论中,将看到这些示例中代码的生成是一个相对机械的转换过程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Some decision-making and creative work was accomplished during design work. It will be seen during the following discussion that the generation of the code in these examples a relatively mechanical translation process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    但是,总的来说,编程工作并不是一个微不足道的代码生成步骤恰恰相反!实际上,在设计建模过程中生成的结果是不完整的第一步;在编程和测试过程中,将进行无数的更改,并发现并解决详细的问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    However, in general, the programming work is not a trivial code generation stepquite the opposite! Realistically, the results generated during design modeling are an incomplete first step; during programming and testing, myriad changes will be made and detailed problems will be uncovered and resolved.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果做得好,在 OO 设计建模过程中产生的想法理解(而不是图表或文档)将提供一个很好的基础,它可以优雅和健壮地扩展,以满足编程过程中遇到的新问题。但是,在编程过程中,要预期并计划大量的变化和与设计的偏差。这是迭代和进化方法中的关键和务实的态度。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Done well, the ideas and understanding (not the diagrams or documents!) generated during OO design modeling will provide a great base that scales up with elegance and robustness to meet the new problems encountered during programming. But, expect and plan for lots of change and deviation from the design during programming. That's a keyand pragmaticattitude in iterative and evolutionary methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      20.2. 将设计映射到代码

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      20.2. Mapping Designs to Code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在面向对象语言中实现需要编写源代码:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Implementation in an object-oriented language requires writing source code for:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 类和接口定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • class and interface definitions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 方法定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • method definitions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以下各节讨论它们在 Java 中的生成(作为一个典型情况)。该讨论或多或少独立于使用 UML 工具生成代码或从某些墙草图工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The following sections discuss their generation in Java (as a typical case). The discussion is more-or-less independent of using a UML tool for code generation or working from some wall sketches.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        20.3. 从 DCD 创建 Class Definitions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        20.3. Creating Class Definitions from DCDs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        至少,DCD 描述了类或接口名称、超类、操作签名和类的属性。这足以在 OO 语言中创建基本类定义。如果 DCD 是在 UML 工具中绘制的,则它可以从图中生成基本类定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        At the very least, DCDs depict the class or interface name, superclasses, operation signatures, and attributes of a class. This is sufficient to create a basic class definition in an OO language. If the DCD was drawn in a UML tool, it can generate the basic class definition from the diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义具有方法签名和属性的类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Defining a Class with Method Signatures and Attributes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        从 DCD 中,映射到 SalesLineItem 的 Java 定义的属性定义(Java 字段)和方法签名非常简单,如图 20.1 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        From the DCD, a mapping to the attribute definitions (Java fields) and method signatures for the Java definition of SalesLineItem is straightforward, as shown in Figure 20.1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 20.1.SalesLineItem 的 Java 版本。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        请注意源代码中添加的 Java 构造函数 SalesLineItem(...)。它派生自发送到 enterItem 交互图中的 SalesLineItemcreate(desc, qty) 消息。这表明在 Java 中,需要一个支持这些参数的构造函数。create 方法通常被排除在类图之外,因为它的通用性和多种解释,具体取决于目标语言。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Note the addition in the source code of the Java constructor SalesLineItem(…). It is derived from the create(desc, qty) message sent to a SalesLineItem in the enterItem interaction diagram. This indicates, in Java, that a constructor supporting these parameters is required. The create method is often excluded from the class diagram because of its commonality and multiple interpretations, depending on the target language.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          20.4. 从交互图创建方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          20.4. Creating Methods from Interaction Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          交互图中的消息序列转换为方法定义中的一系列语句。图 20.2 中的 enterItem 交互图说明了 enterItem 方法的 Java 定义。对于此示例,我们将探讨 Register 及其 enterItem 方法的实现。Register 类的 Java 定义如图 20.3 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The sequence of the messages in an interaction diagram translates to a series of statements in the method definitions. The enterItem interaction diagram in Figure 20.2 illustrates the Java definition of the enterItem method. For this example, we will explore the implementation of the Register and its enterItem method. A Java definition of the Register class is shown in Figure 20.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 20.2.enterItem 交互图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将 enterItem 消息发送到 Register 实例;因此,enterItem 方法在 Register 类中定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The enterItem message is sent to a Register instance; therefore, the enterItem method is defined in class Register.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public void enterItem(ItemID itemID, int qty)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public void enterItem(ItemID itemID, int qty)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          消息 1:getProductDescription 消息发送到 ProductCatalog 以检索 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Message 1: A getProductDescription message is sent to the ProductCatalog to retrieve a ProductDescription.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription desc = catalog.getProductDescription(itemID);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription desc = catalog.getProductDescription(itemID);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          消息 2:makeLineItem 消息将发送到 Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Message 2: The makeLineItem message is sent to the Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          currentSale.makeLineItem(desc, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          currentSale.makeLineItem(desc, qty);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          总之,方法中的每个排序消息(如交互图所示)都映射到 Java 方法中的一个语句。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In summary, each sequenced message within a method, as shown on the interaction diagram, is mapped to a statement in the Java method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          完整的 enterItem 方法及其与交互图的关系如图 20.4 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The complete enterItem method and its relationship to the interaction diagram is shown in Figure 20.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Register.enterItem 方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Register.enterItem Method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 20.3.Register 类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 20.4.enterItem 方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            20.5. 代码中的集合类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            20.5. Collection Classes in Code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            一对多关系很常见。例如,Sale 必须保持对一组许多 SalesLineItem 实例的可见性,如图 20.5 所示。在 OO 编程语言中,这些关系通常是通过引入集合对象(例如 ListMap,甚至是简单的数组)来实现的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            One-to-many relationships are common. For example, a Sale must maintain visibility to a group of many SalesLineItem instances, as shown in Figure 20.5. In OO programming languages, these relationships are usually implemented with the introduction of a collection object, such as a List or Map, or even a simple array.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 20.5.添加集合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,Java 库包含 ArrayListHashMap 等集合类,它们分别实现 ListMap 接口。使用 ArrayList,Sale可以定义一个属性,该属性维护 SalesLineItem 实例的有序列表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, the Java libraries contain collection classes such as ArrayList and HashMap, which implement the List and Map interfaces, respectively. Using ArrayList, the Sale class can define an attribute that maintains an ordered list of SalesLineItem instances.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            集合类的选择当然会受到需求的影响;基于键的查找需要使用 Map,不断增长的有序列表需要 List,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The choice of collection class is of course influenced by the requirements; key-based lookup requires the use of a Map, a growing ordered list requires a List, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            作为一个小问题,请注意 lineItems 属性是根据其接口声明的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            As a small point, note that the lineItems attribute is declared in terms of its interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            指南: 如果对象实现接口,请根据接口而不是具体类声明变量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Guideline: If an object implements an interface, declare the variable in terms of the interface, not the concrete class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,在图 20.5 中,lineItems 属性的定义演示了以下准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, in Figure 20.5 the definition for the lineItems attribute demonstrates this guideline:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private List lineItems = new ArrayList();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private List lineItems = new ArrayList();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              20.6. 异常和错误处理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              20.6. Exceptions and Error Handling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              到目前为止,在解决方案的开发中忽略了异常处理。这是有意关注责任分配和对象设计的基本问题。但是,在应用程序开发中,明智的做法是在设计建模期间(因为它们具有大规模的体系结构影响),当然在实现过程中考虑大规模异常处理策略。简而言之,就 UML 而言,异常可以在消息和操作声明的属性字符串中指示(例如,参见第 256 页)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Exception handling has been ignored so far in the development of a solution. This was intentional to focus on the basic questions of responsibility assignment and object design. However, in application development, it's wise to consider the large-scale exception handling strategies during design modeling (as they have a large-scale architectural impact), and certainly during implementation. Briefly, in terms of the UML, exceptions can be indicated in the property strings of messages and operation declarations (see p. 256, for example).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                20.7. 定义 Sale.makeLineItem 方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                20.7. Defining the Sale.makeLineItem Method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                作为最后一个示例,还可以通过检查 enterItem 协作图来编写类 SalemakeLineItem 方法。交互图的简化版本以及随附的 Java 方法如图 20.6 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As a final example, the makeLineItem method of class Sale can also be written by inspecting the enterItem collaboration diagram. An abridged version of the interaction diagram, with the accompanying Java method, is shown in Figure 20.6.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 20.6.Sale.makeLineItem 方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  20.8. 实现顺序

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  20.8. Order of Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  需要从最小耦合到最耦合实现 classes (理想情况下,进行全面的单元测试)(参见图 20.7)。例如,可能要实现的第一个类是 PaymentProductDescription;next 是仅依赖于先前实现的类ProductCatalogSalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Classes need to be implemented (and ideally, fully unit tested) from least-coupled to most-coupled (see Figure 20.7). For example, possible first classes to implement are either Payment or ProductDescription; next are classes only dependent on the prior implementationsProductCatalog or SalesLineItem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 20.7.类实现和测试的可能顺序。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    20.9. 测试驱动或测试优先开发

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    20.9. Test-Driven or Test-First Development

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    极限编程 (XP) 方法 [Beck00] 推广的一种优秀实践是测试驱动开发 (TDD) 或测试优先开发,该方法适用于 UP 和其他迭代方法(就像大多数 XP 实践一样)。这种做法是先写单元测试代码,先写待测代码,开发者为所有生产代码编写单元测试代码。基本的节奏是写一点测试代码,然后写一点生产代码,让它通过测试,然后再写一些测试代码,依此类推。这将在下一章中更详细地探讨。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    An excellent practice promoted by the Extreme Programming (XP) method [Beck00], and applicable to the UP and other iterative methods (as most XP practices are), is test-driven development (TDD) or test-first development. In this practice, unit testing code is written before the code to be tested, and the developer writes unit testing code for all production code. The basic rhythm is to write a little test code, then write a little production code, make it pass the test, then write some more test code, and so forth. This is explore in more detail in a following chapter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    TDD386

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    TDD p. 386



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      20.10. 将 Designs 映射到代码总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      20.10. Summary of Mapping Designs to Code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如前所述,存在从 UML 类图到类定义,以及从交互图到方法体的转换过程。在编程工作中,仍有很大的创造力、进化和探索空间。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As demonstrated, there is a translation process from UML class diagrams to class definitions, and from interaction diagrams to method bodies. There is still lots of room for creativity, evolution, and exploration during programming work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        20.11. NextGen POS 程序解决方案简介

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        20.11. Introduction to the NextGen POS Program Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本节介绍此迭代的 Java 中类的示例域层。代码生成主要源自设计工作中定义的设计类图和交互图,基于前面探讨的将设计映射到代码的原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This section presents a sample domain layer of classes in Java for this iteration. The code generation is largely derived from the design class diagrams and interaction diagrams defined in the design work, based on the principles of mapping designs to code as previously explored.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此清单的重点是表明存在从设计工件到代码基础的转换。此代码定义了一个简单的情况;它并不是为了说明具有同步、异常处理等功能的健壮的、完全开发的 Java 程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The main point of this listing is to show that there is a translation from design artifacts to a foundation of code. This code defines a simple case; it is not meant to illustrate a robust, fully developed Java program with synchronization, exception handling, and so on.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        为了简洁起见,故意排除了评论,因为代码很简单。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Comments excluded on purpose, in the interest of brevity, as the code is simple.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        课程付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class Payment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // all classes are probably in a package named
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // something like:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        package com.foo.nextgen.domain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Payment
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Money amount;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Payment( Money cashTendered ){ amount = cashTendered; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getAmount() { return amount; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // all classes are probably in a package named
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // something like:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        package com.foo.nextgen.domain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Payment
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Money amount;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Payment( Money cashTendered ){ amount = cashTendered; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getAmount() { return amount; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类 ProductCatalog

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class ProductCatalog

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class ProductCatalog
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Map<ItemID, ProductDescription>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 descriptions = new HashMap()<ItemID, ProductDescription>;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductCatalog()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // sample data
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ItemID id1 = new ItemID( 100 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ItemID id2 = new ItemID( 200 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money price = new Money( 3 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ProductDescription desc;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              desc = new ProductDescription( id1, price, "product 1" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              descriptions.put( id1, desc );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              desc = new ProductDescription( id2, price, "product 2" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              descriptions.put( id2, desc );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductDescription getProductDescription( ItemID id )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return descriptions.get( id );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class ProductCatalog
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Map<ItemID, ProductDescription>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 descriptions = new HashMap()<ItemID, ProductDescription>;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductCatalog()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // sample data
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ItemID id1 = new ItemID( 100 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ItemID id2 = new ItemID( 200 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money price = new Money( 3 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ProductDescription desc;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              desc = new ProductDescription( id1, price, "product 1" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              descriptions.put( id1, desc );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              desc = new ProductDescription( id2, price, "product 2" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              descriptions.put( id2, desc );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductDescription getProductDescription( ItemID id )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return descriptions.get( id );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类寄存器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class Register

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ProductCatalog catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Sale currentSale;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Register( ProductCatalog catalog )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.catalog = catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void endSale()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.becomeComplete();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void enterItem( ItemID id, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ProductDescription desc = catalog.getProductDescription( id );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.makeLineItem( desc, quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makeNewSale()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale = new Sale();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.makePayment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ProductCatalog catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Sale currentSale;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Register( ProductCatalog catalog )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.catalog = catalog;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void endSale()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.becomeComplete();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void enterItem( ItemID id, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ProductDescription desc = catalog.getProductDescription( id );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.makeLineItem( desc, quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makeNewSale()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale = new Sale();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              currentSale.makePayment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类 产品描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ItemID id;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Money price;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private String description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ( ItemID id, Money price, String description )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.id = id;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.price = price;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.description = description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ItemID getItemID() { return id;   }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getPrice() { return price; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public String getDescription() { return description; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ItemID id;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Money price;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private String description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ProductDescription
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ( ItemID id, Money price, String description )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.id = id;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.price = price;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.description = description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public ItemID getItemID() { return id;   }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getPrice() { return price; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public String getDescription() { return description; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        班级销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  new ArrayList()<SalesLineItem>;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Date date = new Date();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private boolean isComplete = false;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Payment payment;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getBalance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return payment.getAmount().minus( getTotal() );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void becomeComplete() { isComplete = true; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public boolean isComplete() { return isComplete; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makeLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ( ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lineItems.add( new SalesLineItem( desc, quantity ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getTotal()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money total = new Money();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money subtotal = null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for ( SalesLineItem lineItem : lineItems )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 subtotal = lineItem.getSubtotal();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 total.add( subtotal );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           return total;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              payment = new Payment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private List<SalesLineItem> lineItems =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  new ArrayList()<SalesLineItem>;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Date date = new Date();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private boolean isComplete = false;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Payment payment;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getBalance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return payment.getAmount().minus( getTotal() );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void becomeComplete() { isComplete = true; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public boolean isComplete() { return isComplete; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makeLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ( ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              lineItems.add( new SalesLineItem( desc, quantity ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getTotal()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money total = new Money();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money subtotal = null;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for ( SalesLineItem lineItem : lineItems )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 subtotal = lineItem.getSubtotal();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 total.add( subtotal );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           return total;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public void makePayment( Money cashTendered )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              payment = new Payment( cashTendered );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类 SalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class SalesLineItem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class SalesLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private int    quantity;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private    ProductDescription    description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public SalesLineItem (ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.description = desc;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.quantity = quantity;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getSubtotal()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return description.getPrice().times( quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class SalesLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private int    quantity;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private    ProductDescription    description;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public SalesLineItem (ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.description = desc;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.quantity = quantity;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Money getSubtotal()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return description.getPrice().times( quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类商店

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Class Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Store
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ProductCatalog catalog = new ProductCatalog();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Register register = new Register( catalog );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Register getRegister() { return register; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public class Store
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private ProductCatalog catalog = new ProductCatalog();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Register register = new Register( catalog );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Register getRegister() { return register; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          20.12. 垄断计划解决方案简介

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          20.12. Introduction to the Monopoly Program Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          本节介绍此迭代的 Java 中类的示例域层。迭代 2 将导致此代码和设计的改进和改进。为了简洁起见,故意排除了评论,因为代码很简单。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This section presents a sample domain layer of classes in Java for this iteration. Iteration-2 will lead to refinements and improvements in this code and design. Comments excluded on purpose, in the interest of brevity, as the code is simple.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          类方

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class Square

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // all classes are probably in a package named
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // something like:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          package com.foo.monopoly.domain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Square
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private String name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Square nextSquare;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private int index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Square( String name, int index )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                this.name = name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                this.index = index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void setNextSquare( Square s )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                nextSquare = s;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Square getNextSquare(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return nextSquare;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public String getName(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public int getIndex()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // all classes are probably in a package named
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // something like:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          package com.foo.monopoly.domain;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Square
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private String name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Square nextSquare;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private int index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Square( String name, int index )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                this.name = name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                this.index = index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void setNextSquare( Square s )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                nextSquare = s;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Square getNextSquare(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return nextSquare;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public String getName(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public int getIndex()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return index;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          类作品

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class Piece

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Piece
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Square location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Piece(Square location)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.location = location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Square getLocation()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void setLocation(Square location)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.location = location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Piece
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           private Square location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Piece(Square location)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.location = location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           public Square getLocation()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void setLocation(Square location)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.location = location;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          类骰子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class Die

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Die
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public static final int MAX  = 6;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private int           faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Die(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                roll(  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void roll(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                faceValue = (int) ( ( Math.random(  ) * MAX ) + 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public int getFaceValue(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Die
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public static final int MAX  = 6;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private int           faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public Die(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                roll(  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void roll(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                faceValue = (int) ( ( Math.random(  ) * MAX ) + 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public int getFaceValue(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return faceValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          班级板

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class Board

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Board
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private static final int SIZE    = 40;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private List             squares = new ArrayList(SIZE);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Board()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              buildSquares();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              linkSquares();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getSquare(Square start, int distance)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              int endIndex = (start.getIndex() + distance) % SIZE;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return (Square) squares.get(endIndex);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getStartSquare()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return (Square) squares.get(0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void buildSquares()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 1; i <= SIZE; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                build(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void build(int i)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square s = new Square("Square " + i, i - 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              squares.add(s);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void linkSquares()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 0; i < (SIZE - 1); i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                link(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square first = (Square) squares.get(0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square last = (Square) squares.get(SIZE - 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              last.setNextSquare(first);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void link(int i)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square current = (Square) squares.get(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square next = (Square) squares.get(i + 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              current.setNextSquare(next);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Board
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private static final int SIZE    = 40;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private List             squares = new ArrayList(SIZE);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Board()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              buildSquares();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              linkSquares();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getSquare(Square start, int distance)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              int endIndex = (start.getIndex() + distance) % SIZE;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return (Square) squares.get(endIndex);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getStartSquare()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return (Square) squares.get(0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void buildSquares()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 1; i <= SIZE; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                build(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void build(int i)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square s = new Square("Square " + i, i - 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              squares.add(s);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void linkSquares()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 0; i < (SIZE - 1); i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                link(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square first = (Square) squares.get(0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square last = (Square) squares.get(SIZE - 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              last.setNextSquare(first);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private void link(int i)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square current = (Square) squares.get(i);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square next = (Square) squares.get(i + 1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              current.setNextSquare(next);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          职业玩家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class Player

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private String name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Player(String name, Die[] dice, Board board)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.name = name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.dice = dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.board = board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              piece = new Piece(board.getStartSquare());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // roll dice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getLocation()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return piece.getLocation();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public String getName()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private String name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Player(String name, Die[] dice, Board board)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.name = name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.dice = dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              this.board = board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              piece = new Piece(board.getStartSquare());
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // roll dice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public Square getLocation()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return piece.getLocation();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public String getName()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return name;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          类 MonopolyGame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Class MonopolyGame

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class MonopolyGame
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private static final int ROUNDS_TOTAL  = 20;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private static final int PLAYERS_TOTAL = 2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private List players = new ArrayList( PLAYERS_TOTAL );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Board   board  = new Board(  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Die[]   dice   = { new Die(), new Die() };
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public MonopolyGame(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Player p;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                p = new Player( "Horse", dice, board );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                players.add( p );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                p = new Player( "Car", dice, board  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                players.add( p );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void playGame(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                for ( int i = 0; i < ROUNDS_TOTAL; i++ )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   playRound();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public List getPlayers(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return players;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private void playRound(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                for ( Iterator iter = players.iterator(  ); iter.hasNext(  ); )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Player player = (Player) iter.next();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   player.takeTurn();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public class MonopolyGame
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private static final int ROUNDS_TOTAL  = 20;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private static final int PLAYERS_TOTAL = 2;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private List players = new ArrayList( PLAYERS_TOTAL );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Board   board  = new Board(  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private Die[]   dice   = { new Die(), new Die() };
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public MonopolyGame(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Player p;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                p = new Player( "Horse", dice, board );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                players.add( p );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                p = new Player( "Car", dice, board  );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                players.add( p );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public void playGame(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                for ( int i = 0; i < ROUNDS_TOTAL; i++ )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   playRound();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             public List getPlayers(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return players;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             private void playRound(  )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                for ( Iterator iter = players.iterator(  ); iter.hasNext(  ); )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Player player = (Player) iter.next();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   player.takeTurn();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            第 21 章.测试驱动开发和重构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Chapter 21. Test-Driven Development and Refactoring

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            逻辑是自信地出错的艺术。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            约瑟夫·伍德·克鲁奇

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Logic is the art of going wrong with confidence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Joseph Wood Krutch

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 在案例研究的背景下介绍这两个重要的开发实践。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Introduce these two important development practices in the context of the case studies.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              极限编程 (XP) 促进了一种重要的测试实践:首先编写测试。它还促进了持续重构代码,以改善其无质量的重复、提高清晰度等。现代工具支持这两种做法,许多 OO 开发人员都对它们的价值发誓。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extreme Programming (XP) promoted an important testing practice: writing the tests first. It also promoted continuously refactoring code to improve its qualityless duplication, increased clarity, and so forth. Modern tools support both practices, and many OO developers swear by their value.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                21.1. 测试驱动开发

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                21.1. Test-Driven Development

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由迭代和敏捷 XP 方法 [Beck00] 推广并适用于 UP(就像大多数 XP 实践一样)的优秀实践是测试驱动开发TDD) [Beck00]。它也被称为测试优先开发。TDD 不仅涵盖单元测试 (测试单个组件),而且本简介将重点介绍其在单元测试单个类中的应用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                An excellent practice promoted by the iterative and agile XP method [Beck00], and applicable to the UP (as most XP practices are), is test-driven development (TDD) [Beck00]. It is also known as test-first development. TDD covers more than just unit testing (testing individual components), but this introduction will focus on its application to unit testing individual classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 OO 单元测试 TDD 样式中,测试代码在要测试的类之前编写,开发人员为几乎所有生产代码编写单元测试代码。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In OO unit testing TDD-style, test code is written before the class to be tested, and the developer writes unit testing code for nearly all production code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                基本的节奏是写一点测试代码,然后写一点生产代码,让它通过测试,然后再写一些测试代码,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The basic rhythm is to write a little test code, then write a little production code, make it pass the test, then write some more test code, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                关键点首先编写测试,想象要测试的代码编写完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Key Point: The test is written first, imagining the code to be tested is written.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                优点包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Advantages include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 单元测试实际上是编写的人类(或至少是程序员)的天性使得避免编写单元测试是很常见的,如果事后才考虑的话。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The unit tests actually get written Human (or at least programmer) nature is such that avoidance of writing unit tests is very common, if left as an afterthought.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 程序员满意度导致测试编写更加一致对于可持续、愉快的测试工作来说,这比听起来更重要。如果遵循传统风格,开发人员首先编写生产代码,非正式地对其进行调试,然后作为事后考虑添加单元测试,那么这不会让人感到满意。这就是 test-last 开发,也称为 Just-this-one-time-I'll-skip-writing-the-test 开发。这是人类的心理。但是,如果先编写测试,我们会感到一个值得的挑战和问题摆在我们面前:我能编写代码来通过这个测试吗?然后,在代码被剪切以通过测试后,会有一些达到目标的成就感。以及一个非常有用的 goalan 可执行、可重复的测试。开发的心理方面不容忽视:编程是人类的努力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Programmer satisfaction leading to more consistent test writing This is more important than it sounds for sustainable, enjoyable testing work. If, following the traditional style, a developer first writes the production code, informally debugs it, and then as an afterthought is expected to add unit tests, it doesn't feel satisfying. This is test-last development, also known as Just-this-one-time-I'll-skip-writing-the-test development. It's human psychology. However, if the test is written first, we feel a worthwhile challenge and question in front of us: Can I write code to pass this test? And then, after the code is cut to pass the tests, there is some feeling of accomplishmentmeeting a goal. And a very useful goalan executable, repeatable test. The psychological aspects of development can't be ignoredprogramming is a human endeavor.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 阐明了详细的界面和行为这听起来很微妙,但在实践中证明它是 TDD 的一个主要价值。如果首先为对象编写测试,请考虑您的心理状态:在编写测试代码时,必须想象对象代码存在。例如,如果在测试代码中编写 sale.makeLineItem(description, 3) 来测试 makeLineItem 方法(尚不存在),则必须仔细考虑方法的公共视图的详细信息:其名称、返回值、参数和行为。该反射改进或阐明了详细设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Clarification of detailed interface and behavior This sounds subtle, but it turns out in practice to be a major value of TDD. Consider your state of mind if you write the test for an object first: As you write the test code, you must imagine that the object code exists. For example, if in your test code you write sale.makeLineItem(description, 3) to test the makeLineItem method (which doesn't exist yet), you must think through the details of the public view of the methodits name, return value, parameters, and behavior. That reflection improves or clarifies the detailed design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 可证明、可重复、自动验证显然,在几周内积累成百上千个单元测试可以提供一些有意义的正确性验证。而且因为它们可以自动运行,所以很容易。随着时间的推移,随着测试基础从 10 个测试构建到 50 个测试再到 500 个测试,随着应用程序规模的增长,编写测试的早期、更痛苦的投资开始真正感觉到它正在得到回报。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Provable, repeatable, automated verification Obviously, having hundreds or thousands of unit tests that build up over the weeks provides some meaningful verification of correctness. And because they can be run automatically, it's easy. Over time, as the test base builds from 10 tests to 50 tests to 500 tests, the early, more painful investment in writing tests starts to really feel like it's paying off as the size of the application grows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 改变现状的信心在 TDD 中,最终将有数百或数千个单元测试,每个生产类都有一个单元测试类。当开发人员需要更改他们自己或其他人编写的现有代码时,有一个可以运行的单元测试套件[1],如果更改导致错误,则提供即时反馈。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [1] CruiseControl 是一种流行的免费开源工具,用于自动重新构建应用程序并运行所有单元测试。在 Web 上找到它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The confidence to change things In TDD, there will eventually be hundreds or thousands of unit tests, and a unit test class for each production class. When a developer needs to change existing codewritten by themselves or othersthere is a unit test suite that can be run[1] , providing immediate feedback if the change caused an error.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [1] A popular free open source tool to automatically re-build the application and run all unit tests is CruiseControl. Find it on the Web.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                最流行的单元测试框架是 xUnit 系列(适用于多种语言),可在 www.junit.org 上获得。[2] 对于 Java,流行的版本是 JUnit。还有一个用于 .NET 的 NUnit,依此类推。JUnit 已集成到大多数流行的 Java IDE 中,例如 Eclipsewww.eclipse.org)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The most popular unit testing framework is the xUnit family (for many languages), available at www.junit.org.[2] For Java, the popular version is JUnit. There's also an NUnit for .NET, and so forth. JUnit is integrated into most of the popular Java IDEs, such as Eclipse (www.eclipse.org).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [2]xUnit 系列和 JUnit 由 Kent Beck(XP 的创建者)和 Eric Gamma(四人组设计模式的作者之一,流行的 Eclipse IDE 的首席架构师)创立。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [2] The xUnit family, and JUnit, was started by Kent Beck (creator of XP) and Eric Gamma (one of the Gang-of-Four design pattern authors, and the chief architect of the popular Eclipse IDE).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                假设我们使用 JUnit 和 TDD 创建 Sale 类。在对 Sale 类进行编程之前,我们在 SaleTest 类中编写一个单元测试方法,该方法执行以下操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Suppose we are using JUnit and TDD to create the Sale class. Before programming the Sale class, we write a unit testing method in a SaleTest class that does the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 创建一个 Sale要测试的事物 (也称为 fixture)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. Create a Salethe thing to be tested (also known as the fixture).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. 使用 makeLineItem 方法向其添加一些行项目(makeLineItem 方法是我们要测试的公共方法)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. Add some line items to it with the makeLineItem method (the makeLineItem method is the public method we wish to test).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5. 请求 total,并使用 assertTrue 方法验证它是否为预期值。如果任何 assertTrue 语句的计算结果未为 true,则 JUnit 将指示失败。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                6. Ask for the total, and verify that it is the expected value, using the assertTrue method. JUnit will indicate a failure if any assertTrue statement does not evaluate to true.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                每种测试方法都遵循以下模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Each testing method follows this pattern:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 创建 Fixture。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. Create the fixture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. 对它执行一些操作 (你想要测试的一些操作)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. Do something to it (some operation that you want to test).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5. 评估结果是否符合预期。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                6. Evaluate that the results are as expected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                需要注意的一个关键点是,我们不会先为 Sale 编写所有单元测试;相反,我们只编写一个测试方法,在 Sale 类中实现解决方案以使其通过,然后重复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A key point to note is that we do not write all the unit tests for Sale first; rather, we write only one test method, implement the solution in class Sale to make it pass, and then repeat.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                要使用 JUnit,必须创建一个扩展 JUnit TestCase 类的测试类;您的 Test 类继承了各种单元测试行为。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To use JUnit, you must create a test class that extends the JUnit TestCase class; your test class inherits various unit testing behaviors.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 JUnit 中,您可以为要测试的每个 Sale 方法创建单独的测试方法。通常,您将为 Sale 类的每个公共方法编写单元测试方法(可能是多个)。例外包括简单的(通常是自动生成的)getset 方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In JUnit you create a separate testing method for each Sale method that you want to test. In general you will write unit testing methods (perhaps several) for each public method of the Sale class. Exceptions include trivial (and usually auto-generated) get and set methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                要测试方法 doFoo,将测试方法命名为 testDoFoo 是一个惯用语。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To test method doFoo, it is an idiom to name the testing method testDoFoo.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public class SaleTest extends TestCase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // test the Sale.makeLineItem method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void testMakeLineItem()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // STEP 1: CREATE THE FIXTURE
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -this is the object to test
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -it is an idiom to name it 'fixture'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -it is often defined as an instance field rather than
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // a local variable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sale fixture = new Sale();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       //  set up supporting objects for the test
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Money total = new Money( 7.5 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Money price = new Money( 2.5 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ItemID id = new ItemID( 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ProductDescription desc =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             new ProductDescription( id, price, "product 1" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // STEP 2: EXECUTE THE METHOD TO TEST
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // NOTE: We write this code **imagining** there
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // is a makeLineItem method. This act of imagination
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // as we write the test tends to improve or clarify
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // our understanding of the detailed interface to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // to the object. Thus TDD has the side-benefit of
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // clarifying the detailed object design.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // test makeLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.makeLineItem( desc, 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.makeLineItem( desc, 2 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // STEP 3: EVALUATE THE RESULTS
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // there could be many assertTrue statements
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // for a complex evaluation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // verify the total is 7.5
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    assertTrue( sale.getTotal().equals( total ));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public class SaleTest extends TestCase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // test the Sale.makeLineItem method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void testMakeLineItem()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // STEP 1: CREATE THE FIXTURE
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -this is the object to test
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -it is an idiom to name it 'fixture'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // -it is often defined as an instance field rather than
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // a local variable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sale fixture = new Sale();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       //  set up supporting objects for the test
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Money total = new Money( 7.5 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Money price = new Money( 2.5 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ItemID id = new ItemID( 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ProductDescription desc =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             new ProductDescription( id, price, "product 1" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // STEP 2: EXECUTE THE METHOD TO TEST
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // NOTE: We write this code **imagining** there
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // is a makeLineItem method. This act of imagination
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // as we write the test tends to improve or clarify
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // our understanding of the detailed interface to
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // to the object. Thus TDD has the side-benefit of
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // clarifying the detailed object design.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // test makeLineItem
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.makeLineItem( desc, 1 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.makeLineItem( desc, 2 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // STEP 3: EVALUATE THE RESULTS
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // there could be many assertTrue statements
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // for a complex evaluation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // verify the total is 7.5
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    assertTrue( sale.getTotal().equals( total ));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                只有在编写了这个 testMakeLineItem 测试方法之后,我们才会编写 SalemakeLineItem 方法通过此测试。因此,术语测试驱动或测试优先开发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Only after this testMakeLineItem test method is written do we then write the Sale.makeLineItem method to pass this test. Hence, the term test-driven or test-first development.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                IDE 对 TDD 和 xUnit 的支持

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                IDE Support for TDD and xUnit

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                大多数 IDE 都内置了对某些 xUnit 工具的支持。例如,Eclipse 支持 JUnit。JUnit 包含一个视觉提示,如果所有测试在执行时都通过,则会显示一个绿色条。这产生了 TDD 的口号:保持条形图为绿色,以保持代码的整洁图 21.1 说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Most IDEs have built-in support for some xUnit tool. For example, Eclipse supports JUnit. JUnit includes a visual cueif all the tests pass when executed, it displays a green bar. This gave rise to the TDD mantra: Keep the bar green to keep the code clean. Figure 21.1 illustrates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 21.1.在流行的 IDE Eclipse 中支持 TDD 和 JUnit。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  21.2. 重构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  21.2. Refactoring

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  重构 [Fowler99] 是一种结构化的、有纪律的方法,用于在不改变其外部行为的情况下重写或重构现有代码,应用小的转换步骤,并结合重新执行每个步骤的测试。持续重构代码是另一种 XP 实践,适用于所有迭代方法(包括 UP)。[3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Refactoring [Fowler99] is a structured, disciplined method to rewrite or restructure existing code without changing its external behavior, applying small transformation steps combined with re-executing tests each step. Continuously refactoring code is another XP practice and applicable to all iterative methods (including the UP).[3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [3] Ralph Johnson(四人组设计模式作者之一)和 Bill Opdyke 于 1990 年首次讨论重构。Kent Beck(XP 创建者)和 Martin Fowler 是另外两位重构先驱。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [3] Ralph Johnson (one of the Gang-of-Four design pattern authors) and Bill Opdyke first discussed refactoring in 1990. Kent Beck (XP creator), along with Martin Fowler, are two other refactoring pioneers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  重构的本质是一次应用一个小的行为保留转换(每个转换称为“重构”)。每次转换后,都会重新执行单元测试,以证明重构不会导致回归(失败)。因此,重构和 TDD 之间存在关系所有这些单元测试都支持重构过程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The essence of refactoring is applying small behavior preserving transformations (each called a 'refactoring'), one at a time. After each transformation, the unit tests are re-executed to prove that the refactoring did not cause a regression (failure). Therefore, there's a relationship between refactoring and TDDall those unit tests support the refactoring process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  每次重构都很小,但当然,在再次执行单元测试之前进行一系列转换可以产生代码和设计的重大重组(变得更好),同时确保行为保持不变。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Each refactoring is small, but a series of transformationseach followed by executing the unit tests againcan, of course, produce a major restructuring of the code and design (for the better), all the while ensuring the behavior remains the same.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  重构的活动和目标是什么?它们只是优秀编程的活动和目标:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What are the activities and goals refactoring? They are simply the activities and goals of good programming:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 删除重复代码

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • remove duplicate code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 提高清晰度

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • improve clarity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 缩短长方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • make long methods shorter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 删除硬编码文本常量的使用

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • remove the use of hard-coded literal constants

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 以及更多...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • and more…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  经过良好重构的代码简短、紧凑、清晰,并且没有重复它看起来就像一个高级程序员的工作。不具备这些品质的代码闻起来很臭或有代码异味。换句话说,有一个糟糕的设计。代码味道是重构中的一个隐喻,它们暗示代码中可能存在问题。选择名称代码 smell 是为了表明,当我们查看 smelly code 时,它可能被证明是好的,不需要改进。这与代码恶臭形成鲜明对比,真正腐烂的代码急需清理!一些代码味道包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Code that's been well-refactored is short, tight, clear, and without duplicationit looks like the work of a master programmer. Code that doesn't have these qualities smells bad or has code smells. In other words, there is a poor design. Code smells is a metaphor in refactoringthey are hints that something may be wrong in the code. The name code smell was chosen to suggest that when we look into the smelly code, it might turn out to be alright and not need improvement. That's in contrast to code stenchtruly putrid code crying out for clean up! Some code smells include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 重复的代码

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • duplicated code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Big 方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • big method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 具有许多实例变量的类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • class with many instance variables

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 包含大量代码的类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • class with lots of code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 惊人相似的子职业

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • strikingly similar subclasses

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 在设计中很少或根本不使用接口

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • little or no use of interfaces in the design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 许多对象之间的高耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • high coupling between many objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 以及许多其他编写 Bad Code 的方式......[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [4] 有关代码味道和重构的许多 Wiki 页面,请参阅原始和主要的 OO、模式、XP 和重构 Wiki c2.com/cgi/wiki。迷人的地方...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • and so many other ways bad code is written…[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [4] See the original and major OO, patterns, XP, and refactoring Wiki c2.com/cgi/wiki for many Wiki pages on code smells and refactoring. Fascinating site…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  解决臭代码的方法是重构。与模式一样,重构也有名称,例如 Extract Method。大约有 100 个命名重构;下面是一个示例来了解它们:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The remedy to smelly code are the refactorings. Like patterns, refactorings have names, such as Extract Method. There are about 100 named refactorings; here's a sample to get a sense of them:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  重构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Refactoring

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Description

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  提取方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extract Method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  通过将一部分分解为私有 helper 方法,将长方法转换为较短的方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Transform a long method into a shorter one by factoring out a portion into a private helper method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  提取常量

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extract Constant

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将文本常量替换为常量变量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Replace a literal constant with a constant variable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  引入解释变量(Extract Local Variable 的特化)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Introduce Explaining Variable (specialization of Extract Local Variable)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将表达式的结果或表达式的一部分放在一个临时变量中,该变量的名称可以说明目的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将构造函数调用替换为 Factory Method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Replace Constructor Call with Factory Method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  例如,在 Java 中,将使用 new 运算符和构造函数调用替换为调用创建对象的帮助程序方法(隐藏详细信息)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In Java, for example, replace using the new operator and constructor call with invoking a helper method that creates the object (hiding the details).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此示例演示了常见的 Extract Method 重构。请注意,在图 21.2 列表中,Player 类中的 takeTurn 方法有一个初始代码段,用于掷骰子并在循环中计算总数。此代码本身是一个独特的、有凝聚力的行为单元;我们可以通过将 takeTurn 方法提取到名为 rollDice 的私有帮助程序方法中,使 takeTurn 方法更短、更清晰,并更好地支持 High Cohesion。请注意,takeTurn 中需要 rollTotal 值,因此此帮助程序方法必须返回 rollTotal[5]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This example demonstrates the common Extract Method refactoring. Notice in the Figure 21.2 listing that the takeTurn method in the Player class has an initial section of code that rolls the dice and calculates the total in a loop. This code is itself a distinct, cohesive unit of behavior; we can make the takeTurn method shorter, clearer, and better supporting High Cohesion by extracting that code into a private helper method called rollDice. Notice that the rollTotal value is required in takeTurn, so this helper method must return the rollTotal.[5]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [5] 这违反了 Command-Query 分离原则(第 358 页),但对于私有方法,该原则更容易放宽。这是一个指导方针,而不是一条规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [5] That violates the Command-Query Separation Principle (p. 358), but the principle is more easily relaxed for private methods. It is a guideline, not a rule.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.2.重构之前的 takeTurn 方法。
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         // roll dice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         // roll dice
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  现在是应用 Extract Method 重构后的代码:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Now here's the code after applying the Extract Method refactoring:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.3.使用 Extract Method 重构后的代码。
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         // the refactored helper method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = rollDice();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  private int rollDice()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return rollTotal;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class Player
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Piece  piece;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Board  board;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     private Die[]  dice;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public void takeTurn()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         // the refactored helper method
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = rollDice();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Square newLoc = board.getSquare(piece.getLocation(), rollTotal);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     piece.setLocation(newLoc);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  private int rollDice()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     int rollTotal = 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for (int i = 0; i < dice.length; i++)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        dice[i].roll();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        rollTotal += dice[i].getFaceValue();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return rollTotal;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们将在迭代 2 中看到,这个 rollDice 辅助方法不是一个很好的解决方案,Pure Fabrication 模式将提出一个替代方案,该替代方案也保留了 Command-Query 分离原则,但它足以说明重构操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We will see in iteration-2 that this rollDice helper method is not a great solutionthe Pure Fabrication pattern will suggest an alternative that also preserves the Command-Query Separation Principlebut it suffices to illustrate the refactoring operation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  作为第二个简短的示例,我最喜欢的简单重构之一是 Introduce Explaining Variable,因为它阐明、简化和减少了对注释的需求。图 21.4图 21.5 中的清单说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As a second short example, one of my favorite simple refactorings is Introduce Explaining Variable because it clarifies, simplifies, and reduces the need for comments. The listings in Figure 21.4 and Figure 21.5 illustrate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.4.在引入解释变量之前。
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // good method name, but the logic of the body is not clear
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  boolean isLeapYear( int year )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return( ( ( year % 400 ) == 0 ) ||
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ( ( ( year % 4 ) == 0 ) && ( ( year % 100 ) != 0 ) ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // good method name, but the logic of the body is not clear
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  boolean isLeapYear( int year )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return( ( ( year % 400 ) == 0 ) ||
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           ( ( ( year % 4 ) == 0 ) && ( ( year % 100 ) != 0 ) ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.5.在引入解释变量之后。
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // that's better!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  boolean isLeapYear( int year )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean isFourthYear = ( ( year % 4 ) == 0 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean isHundrethYear = ( ( year % 100 ) == 0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean is4HundrethYear = ( ( year % 400 ) == 0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return (
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        is4HundrethYear
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        || ( isFourthYear && ! isHundrethYear ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // that's better!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  boolean isLeapYear( int year )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean isFourthYear = ( ( year % 4 ) == 0 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean isHundrethYear = ( ( year % 100 ) == 0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     boolean is4HundrethYear = ( ( year % 400 ) == 0);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     return (
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        is4HundrethYear
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        || ( isFourthYear && ! isHundrethYear ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  IDE 对重构的支持

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  IDE Support for Refactoring

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  大多数占主导地位的 IDE 都包含自动重构支持。参见图 21.6图 21.7 在 Eclipse IDE 中应用 Extract Method 重构的示例。rollDice 方法是自动生成的,从 takeTurn 方法对它的调用也是如此。请注意,该工具足够智能,可以看到需要返回 rollTotal 变量。好!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Most of the dominant IDEs include automated refactoring support. See Figure 21.6 and Figure 21.7 for an example in the Eclipse IDE of applying the Extract Method refactoring. The rollDice method is automatically generated, as is the call to it from the takeTurn method. Notice that the tool is smart enough to see the need to return the rollTotal variable. Nice!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.6.IDE 之前。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 21.7.重构后的 IDE。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    21.3. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    21.3. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    对于 Web 上的 TDD:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For TDD on the Web:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    书中有一些有用的文本,包括 Beck 的 Test Driven Development: By Example、Atels 的 Test Driven Development 和 Rainsberger 的 JUnit Recipes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    There are several useful texts, including Test Driven Development: By Example by Beck, Test Driven Development by Astels, and JUnit Recipes by Rainsberger.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    对于 Web 上的重构:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For refactoring on the Web:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    经典的代码级重构文本是 Martin Fowler 编写的 Refactoring: Improving the Design of Existing Code。在更高的设计级别上,Joshua Kerievsky 的 Refactoring to Patterns 也非常出色。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The classic code-level refactoring text is Refactoring: Improving the Design of Existing Code by Martin Fowler. Also excellent, at a higher design level, is Refactoring to Patterns by Joshua Kerievsky.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第 22 章.UML 工具和 UML 作为蓝图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chapter 22. UML Tools and UML as Blueprint

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      经验是那种奇妙的东西,它使你能够在再次犯错误时认识到错误。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      F. P. 琼斯

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Experience is that marvelous thing that enables you to recognize a mistake when you make it again.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      F. P. Jones

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 定义正向、反向和往返工程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Define forward, reverse, and round-trip engineering.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 有关选择 UML 工具的建议。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Suggestions for choosing a UML tool.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 有关如何集成 UML 墙草图和工具的建议。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Suggestions on how to integrate UML wall sketching and tools.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        详细讨论特定的 UML 工具没有用,因为这是一个快速变化的主题信息很快就会过时。但是,本章指出了一些常见功能以及“UML 作为蓝图”的工具的使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        It isn't useful to discuss specific UML tools in detail because this is a rapidly changing subjectinformation is quickly stale. However, this chapter points out some common features and the use of such tools for "UML as blueprint."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如前所述,人们希望应用 UML 的三种方式包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As mentioned, three ways people wish to apply UML include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML 作为 sketch

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML as sketch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML 作为蓝图这适用于代码和关系图生成。相对详细的图表指导使用工具生成一些代码(例如 Java)。从代码生成图表以可视化代码库。生成代码后,开发人员通常会在编程时填写许多精细的细节。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML as blueprint This applies to both code and diagram generation. Relatively detailed diagrams guide some code generation (e.g., Java) with a tool. And diagrams are generated from the code to visualize the code base. After generating code, many fine details are usually filled in by developers while programming.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML 作为编程语言UML 中软件系统的完整可执行规范。可执行代码将自动生成(或虚拟机直接解释 UML),但开发人员通常不会看到或修改这些代码;一个只能在 UML “编程语言” 中工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UML as programming language Complete executable specification of a software system in UML. Executable code will be automatically generated (or a virtual machine directly interprets UML), but is not normally seen or modified by developers; one works only in the UML "programming language."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        第一种和第二种方式很常见。大多数 UML 工具都支持第二种方法,即 UML 作为蓝图,而不是 UML 作为编程语言。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The first and second ways are common. Most UML tools support the second approach, UML as blueprint, rather than UML as programming language.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          22.1. 正向、反向和往返工程

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          22.1. Forward, Reverse, and Round-Trip Engineering

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          CASE(计算机辅助软件工程)工具世界中,正向工程意味着从图表生成代码;逆向工程意味着从代码生成图表,而往返工程则闭合循环该工具支持在任一方向上生成,并且可以在 UML 图和代码之间同步,理想情况下,当任何一个发生更改时,它们都会自动同步。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the CASE (Computer Aided Software Engineering) tool world, forward engineering means the generation of code from diagrams; reverse engineering means generation of diagrams from code and round-trip engineering closes the loopthe tool supports generation in either direction and can synchronize between UML diagrams and code, ideally automatically and immediately as either is changed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          所有 UML 工具都声称支持这些功能,但许多工具都已完全失效。为什么?因为许多工具只能执行静态模型:它们可以从代码生成类图,但不能生成交互图。或者对于正向工程,他们可以从类图生成基本(例如 Java)类定义,但不能从交互图生成方法体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          All UML tools claim to support these features, but many are half crippled. Why? Because many of the tools can only do the static models: They can generate class diagrams from code, but can't generate interaction diagrams. Or for forward engineering, they can generate the basic (e.g., Java) class definition from a class diagram, but not the method bodies from interaction diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          然而,代码不仅仅是变量的声明,它是动态行为!例如,假设您想要了解现有应用程序或框架的基本调用流结构。如果您的工具可以从代码生成序列图,那么您可以更轻松地遵循系统的调用流逻辑来学习其基本协作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Yet, code isn't just declarations of variables, it's dynamic behavior! For example, suppose you want to understand the basic call-flow structure of an existing application or framework. If your tool can generate a sequence diagram from the code, you can then much more easily follow the call-flow logic of the system to learn its basic collaborations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            22.2. 什么是有价值特征的通用报告?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            22.2. What is a Common Report of Valuable Features?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            多年来,我有机会拜访或咨询了许多尝试过 UML 工具的大客户。相当一致的是,开发人员在尝试了一段时间后最终报告说,它似乎比帮助(与简单的文本功能强大的 IDE 相比)更 “妨碍” ”。这并不总是正确的我报告的是平均值。而且,价值体验似乎随着每一代新工具的推出而得到改善。综上所述,我听到客户声称的 UML 工具价值最一致的长期报告是它们对逆向工程的价值,作为理解现有代码的可视化学习辅助工具。当开发人员想要“了解”大型代码库时,从代码生成 UML 包、类和交互图,然后在监视器上查看图表,或将它们打印在大型绘图仪纸上,似乎始终很有用。我同意。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Over the years, I've had the opportunity to visit or consult with many large clients who have tried UML tools. Rather consistently, the developers eventually report, after trying the tool for some time, that it seems to "get in the way" more than help (versus simply a text-powerful IDE). This is not always trueI'm reporting averages. And, the experience of value seems to improve with each new generation of tools. All that said, the most consistent long-term report of UML tool value that I hear clients claim is their value for reverse engineering, as a visualization learning aid to understand existing code. Generating UML package, class, and interaction diagrams from code and then viewing the diagrams on a monitor, or printing them on large plotter paper, seems to consistently be useful when developers want to "get their head around" a large code base. And I agree.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            随着时间的推移,随着越来越多的 UML 工具与文本强 IDE(如 Eclipse 和 Visual Studio)完美集成,并且它们的可用性得到提高,我预测在将这些工具用于前向和往返工程时,将报告出更一致的价值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            With time, as more UML tools become well-integrated with text-strong IDEs (such as Eclipse and Visual Studio), and their usability improves, I predict that there will be more consistent value reported in using the tools for both forward and round-trip engineering.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              22.3. 在工具中寻找什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              22.3. What to Look For in a Tool?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              鉴于上述评论,以下是选择 UML 工具时的一些建议摘要,这些建议基于客户在花了太多钱后通常事后与我分享的内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Given the above comments, here's a summary of some advice when choosing a UML tool, based on what clientsoften in hindsight after spending too much moneyhave shared with me.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 首先,尝试使用免费的 UML 工具。有几种选择。只有在免费选项用完后才购买工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • First, try a free UML tool. There are several options. Only buy a tool after the free options have been exhausted.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 一旦您选择了试探性工具,尤其是在公司标准工具或大型购买决策的上下文中,请在做出决定之前与尽可能多的开发人员一起在实际项目中试用它。根据真正长期使用它的开发人员的指导来决定,而不是根据架构师或其他只是粗略调查的人的意见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Once you've chosen a tentative tool, especially in the context of a company-standard tool or a large purchasing decision, try it on a real project with as many developers as possible, before making a decision. Decide based on the guidance of your developers who have really used it for a long period, not based on the opinion of architects or others who have only made a cursory investigation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 选择集成到您最喜欢的文本强 IDE 中的 UML 工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Choose a UML tool that integrates into your favorite text-strong IDE.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 选择支持从代码中对序列图进行逆向工程的 UML 工具。或者,如果其他令人满意的免费工具不支持此功能,请使用大多数开发人员的免费工具,并购买一些支持此功能的商业工具副本,以备不时之需。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Choose a UML tool that supports reverse engineering sequence diagrams from code. Or, if an otherwise satisfactory free tool doesn't support this, use the free tool for most developers, and buy just a few copies of a commercial tool that does, for when you want to understand call-flow patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 选择一种支持在大型绘图仪纸张上以大字体和图表大小打印输出到绘图仪的工具,以便进行大规模可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Choose a tool that supports printouts to a plotter, on large plotter paper, in large font and diagram sizes, so that large-scale visualization is possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                22.4. 如果绘制 UML,编码后如何更新图表?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                22.4. If Sketching UML, How to Update the Diagrams After Coding?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如果您使用的是与 IDE 集成的 UML 工具,单独工作,而不是进行墙面绘制,那么同步图表是 IDE 中的简单逆向工程操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you are using a UML tool integrated with an IDE, working alone, and not doing wall sketching, then synchronizing the diagrams is a simple reverse-engineering operation in the IDE.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                但是,如果你正在与一个小团队合作,并且希望在每次迭代中花一天时间在白板上建模,将 UML 作为草图应用,该怎么办?请考虑以下场景:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                But what if you are working with a small team and want to spend a modeling day each iteration at the whiteboards, applying UML as sketch. Consider this scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                1. 在为期三周的 timeboxed 迭代开始时,有一个涉及 UML 墙草图的建模日。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                2. At the start of a three-week timeboxed iteration, there was a modeling day involving UML wall sketches.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                3. 接下来是大约三周的代码和测试。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                4. This is followed by about three weeks of code and test.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5. 最后,是时候开始下一次迭代的建模日了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                6. Finally, it's time to start the next iteration's modeling day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                此时,如果你想再次做一些墙面草图,基于代码库的现有状态,怎么进行呢?这里有一个建议:在建模日之前,使用 UML 工具将代码逆向工程为 UML 图包、类和交互图。然后,对于最有趣的,在绘图仪上将它们大打印在长绘图仪纸上。将它们挂在建模室的墙壁上相对较高的位置,这样在建模日期间,开发人员可以参考它们,在它们上面画草图,并在白板或静态粘贴板上在下面画草图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                At this point, if you wanted to do some wall sketching again, based on the existing state of the code base, how to proceed? Here's a suggestion: Just before the modeling day, use a UML tool to reverse engineer the code into UML diagramspackage, class, and interaction diagrams. Then, for the most interesting ones, print them large on long plotter paper, on a plotter. Hang them relatively high in the modeling room on the walls, so that during the modeling day developers can refer to them, sketch on top of them, and sketch below them on whiteboards or static cling sheets.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  22.5. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  22.5. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  软件工具自然是一个瞬息万变的主题。一个相对完整的 UML 工具列表维护在:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software tools are naturally a fast-changing subject. A relatively complete list of UML tools is maintained at:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  www.objectsbydesign.com/tools/umltools_byCompany.html

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  www.objectsbydesign.com/tools/umltools_byCompany.html

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    第 23 章.快速分析更新

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Chapter 23. Quick Analysis Update

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    任何足够高级的 bug 都与功能没有区别。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    里奇·库拉维茨

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Any sufficiently advanced bug is indistinguishable from a feature.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Rich Kulawiec

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 快速突出显示一些分析工件更改,尤其是在 Monopoly 域模型中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Quickly highlight some analysis artifact changes, especially in the Monopoly domain model.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      本章简要指出了需求和域分析中的一些变化。值得注意的建模和 UML 提示与 NextGen SSD 和 Monopoly 域模型有关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This chapter briefly points out some changes in the requirements and domain analysis. The noteworthy modeling and UML tips of interest are related to the NextGen SSDs and the Monopoly domain model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        23.1. 案例研究:NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        23.1. Case Study: NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        使用案例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Use Cases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此迭代的用例不需要优化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        No refinement is needed for the use cases this iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        然而,在流程层面上,我建议(就像 UP 一样)在这个迭代中(接近迭代 1 结束,再次接近迭代 2 结束)进行第二次为期一两天的简短需求研讨会,在此期间将调查和详细编写更多需求。之前全面分析的用例(例如,Process Sale)将被重新审视,并可能根据从迭代 1 编程和测试中获得的见解进行优化。在迭代方法中,请注意早期编程和测试与并行需求分析的相互作用,这种分析通过早期开发的反馈得到改进。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        However, at a process level I recommend (as does the UP) a second short one- or two-day requirements workshop this iteration (near the end of iteration-1 and again near the end of iteration-2), within which more requirements will be investigated and written in detail. The previously fully analyzed use cases (for example, Process Sale) will be revisited and probably refined based on insights gained from iteration-1 programming and tests. In iterative methods, note the interplay of early programming and testing with parallel requirements analysis that is improved by feedback from early development.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SSD 固态硬盘

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SSDs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此迭代包括添加对具有不同接口的第三方外部系统(如税收计算器)的支持。NextGen POS 系统将与外部系统进行远程通信。因此,应更新 SSD 以至少反映一些系统间协作,以阐明新的系统级事件是什么。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This iteration includes adding support for third-party external systems with varying interfaces, such as a tax calculator. The NextGen POS system will be remotely communicating with external systems. Consequently, the SSDs should be updated to reflect at least some of the inter-system collaborations, in order to clarify what the new system-level events are.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 23.1 说明了一种通过信用支付的场景的 SSD,这需要与多个外部系统协作。尽管在这个迭代中没有处理信用支付的设计,但建模者(我)已经基于它绘制了一个 SSD(可能还有其他几个),以更好地理解系统间协作,从而更好地支持外部系统中不同的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Figure 23.1 illustrates an SSD for one scenario of paying by credit, which requires collaboration with several external systems. Even though the design of paying by credit is not handled in this iteration, the modeler (me) has drawn an SSD based on it (and probably several others as well), to better understand the inter-system collaboration, and thus the required support for varying interfaces in the external systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 23.1.一个 SSD 方案,用于说明一些外部系统。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在领域建模方面有一点经验之后,建模者可以估计一组新需求在许多新概念、关联和属性方面是否会对领域模型产生轻微或主要的影响。与之前的迭代相比,这次解决的需求不涉及很多新的领域概念。对新需求的简要调查表明,将 PriceRule 之类的东西作为一个领域概念,但可能没有几十个新事物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        After a little experience in domain modeling, a modeler can estimate if a set of new requirements will have a minor or major impact on the Domain Model in terms of many new concepts, associations, and attributes. In contrast to the prior iteration, the requirements being tackled this time do not involve many new domain concepts. A brief survey of the new requirements suggests something like PriceRule as a domain concept, but there are probably not dozens of new things.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在这种情况下,跳过优化领域模型,快速进行设计工作是相当合理的,让新的领域概念的发现发生在设计模型中的对象设计期间,当开发人员正在思考解决方案时,甚至在编码时。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In this situation, it is quite reasonable to skip refining the Domain Model, move quickly on to design work, and let the discovery of new domain concepts occur during object design in the Design Model, when the developers are thinking through a solution, or indeed even while coding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UP 流程成熟的一个标志是了解何时创建工件会增加重要价值,或者是一种机械的“开始工作”步骤,最好跳过。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A sign of process maturity with the UP is understanding when creating an artifact will add significant value, or is a kind of mechanical "make work" step and better skipped.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另一方面,建模不仅可能太多,而且可能太少。开发人员通常会避免进行任何分析或建模,因为这似乎是一件价值低且耗时的事情。然而,如果一个人掌握了分析和设计的基本准则,熟悉了“语言”,无论是用例还是 UML 或墙上的 UI 原型,并本着敏捷建模的精神应用这些,那么建模可以增加价值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        On the other hand, there can be not only too much modeling, but too little. Developers often avoid any analysis or modeling because it seems like a low-value and time-consuming affair. Yet, modeling can add value if one masters the basic guidelines of analysis and design, becomes comfortable with the "languages"be they use cases or UML or UI prototypes on a walland applies these in the spirit of agile modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        系统运营合同

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        System Operation Contracts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在此迭代中未考虑新的系统操作,因此不需要 Contract。无论如何,只有当合同提供的详细精度比用例中的描述有所改进时,才可以考虑合同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        No new system operations are being considered in this iteration, and thus contracts are not required. In any event, contracts are only an option to consider when the detailed precision they offer is an improvement over the descriptions in the use cases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          23.2. 案例研究:垄断

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          23.2. Case Study: Monopoly

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          用例等

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Use Cases, etc.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          用例被跳过了,因为大多数人都知道游戏规则。无需更新 SSD,也无需编写任何运营合同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Uses case were skipped, as most know the rules of the game. No update to the SSD is required, and no operations contracts were written.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          概念 Square、GoSquare、IncomeTaxSquareGoToJailSquare 都很相似它们都是正方形的变体。在这种情况下,可以(并且通常有用)将它们组织成泛化-专业化类层次结构(或简称类层次结构),其中超类 Square 表示更通用的概念,而子类代表更专业的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The concepts Square, GoSquare, IncomeTaxSquare, and GoToJailSquare are all similarthey are variations on a square. In this situation, it is possible (and often useful) to organize them into a generalization-specialization class hierarchy (or simply class hierarchy) in which the superclass Square represents a more general concept and the subclasses more specialized ones.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在 UML 中,泛化-特化关系用一个大三角形箭头表示,从特化类指向更通用的类,如图 23.2 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the UML, generalization-specialization relationships are shown with a large triangular arrow pointing from the specialization class to the more general class, as shown in Figure 23.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 23.2.迭代 2 的 Monopoly 域模型更改。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          泛化是识别概念之间的共性并定义超类(一般概念)和子类(专业概念)关系的活动。这是一种在概念之间构建分类分类的方法,然后在类层次结构中进行说明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Generalization is the activity of identifying commonality among concepts and defining superclass (general concept) and subclass (specialized concept) relationships. It is a way to construct taxonomic classifications among concepts that are then illustrated in class hierarchies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          泛化和专业化的主题将在后面的章节中更彻底地介绍。请参阅第 509 页的“概括”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The subject of generalization and specialization is covered more thoroughly in a later chapter. See "Generalization" on page 509.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          识别超类和子类在域模型中很有价值,因为它们的存在使我们能够以更一般、更精细和更抽象的术语来理解概念。它导致表达经济、理解力提高和重复信息减少。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Identifying a superclass and subclasses is of value in a domain model because their presence allows us to understand concepts in more general, refined and abstract terms. It leads to economy of expression, improved comprehension and a reduction in repeated information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          何时显示子类?以下是常见的动机:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When to show subclasses? The following are common motivations:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在以下情况下创建超类的概念子类:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Create a conceptual subclass of a superclass when:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. 该子类具有其他感兴趣的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. The subclass has additional attributes of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. 该子类具有其他相关关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. The subclass has additional associations of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          5. 子类概念的操作、处理、反应或操作方式与超类或其他子类不同,值得注意。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          6. The subclass concept is operated on, handled, reacted to, or manipulated differently than the superclass or other subclasses, in noteworthy ways.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          标准 #3 适用于不同种类的方格的情况。根据域规则,GoSquare 的处理方式与其他类型的 Square不同。这是一个值得注意的独特概念,域模型作为识别值得注意的概念的地方特别有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Criteria #3 applies to the case of the different kinds of squares. The GoSquare is treated differently than other kinds of squares according to the domain rules. It is a noteworthy distinct conceptand the domain model is especially useful as a place to identify noteworthy concepts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因此,更新的域模型如图 23.2 所示。请注意,域规则对每个不同 square 的处理方式都显示为一个单独的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Therefore, an updated domain model is shown in Figure 23.2. Note that each distinct square that is treated differently by the domain rules is shown as a separate class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南: 此模型说明了更多域建模准则和要点:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guidelines: A few more domain modeling guidelines and points are illustrated in this model:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Square 被定义为 {abstract}

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 指南: 声明超类抽象。尽管这是一个与软件无关的概念视角,但所有软件超类都是抽象的也是一个常见的 OO 准则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The class Square is defined {abstract}.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Guideline: Declare superclasses abstract. Although this is a conceptual perspective unrelated to software, it is also a common OO guideline that all software superclasses be abstract.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 每个子类名称都会附加超类名称IncomeTaxSquare,而不是 IncomeTax。这是一个很好的成语,也更准确,因为,例如,我们真的不是在对所得税的概念进行建模,而是在垄断游戏中对所得税方格的概念进行建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 指南: 将超类名称附加到子类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Each subclass name appends the superclass nameIncomeTaxSquare rather than IncomeTax. That's a good idiom, and also more accurate, as, for example, we really aren't modeling the concept of income tax, but modeling the concept of an income tax square in a monopoly game.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Guideline: Append the superclass name to the subclass.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 没什么特别的 RegularSquare 也是一个独特的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • A RegularSquare that does nothing special is also a distinct concept.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 现在涉及到金钱,玩家有一个 cash 属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Now that money is involved, the Player has a cash attribute.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            第 24 章.迭代 2More Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Chapter 24. Iteration 2More Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 定义迭代 2 的要求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Define the requirements for iteration-2.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              初始阶段章节和细化阶段的迭代 1 章节强调了广泛的基本分析和对象设计技能,以便共享有关构建对象系统的广泛常见步骤的信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The inception phase chapters and those for iteration-1 in the elaboration phase emphasized a wide range of fundamental analysis and object design skills, in order to share information on a breadth of common steps in building object systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在这个迭代中,案例研究只是强调:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In this iteration, the case study just emphasizes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 基本对象设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • essential object design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 使用图案创建实体设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • the use of patterns to create a solid design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 应用 UML 以可视化模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • applying the UML to visualize the models

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这些是本书的主要目标和关键技能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              These are primary objectives of the book, and critical skills.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对需求分析或领域建模的讨论很少,对设计的解释更加简洁,现在(在迭代 1 中)已经详细解释了如何在对象中思考的基础知识。当然,许多其他分析、设计和实现活动将在此迭代中进行,但这些活动被淡化,以支持共享有关如何进行对象设计的信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              There is minimal discussion of requirements analysis or domain modeling, and the explanation of the design is more succinct, now that (in iteration-1) a detailed explanation of the basics of how to think in objects has been presented. Many other analysis, design, and implementation activities would of course occur in this iteration, but these are de-emphasized in favor of sharing information about how to do object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                24.1. 从迭代 1 到 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                24.1. From Iteration 1 to 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当迭代 1 结束时,应完成以下操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When iteration-1 ends, the following should be accomplished:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 所有软件都经过了严格的测试:单元、验收、负载、可用性等。UP 的理念是对质量和正确性进行早期、现实和持续的验证,以便早期反馈指导开发人员适应和改进系统,找到其“正确路径”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • All the software has been vigorously tested: unit, acceptance, load, usability, and so on. The idea in the UP is to do early, realistic, and continuous verification of quality and correctness, so that early feedback guides the developers to adapt and improve the system, finding its "true path."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 客户定期参与对部分系统的评估,以获得反馈以调整和澄清需求。客户可以尽早看到系统的明显进展。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Customers have been regularly engaged in evaluating the partial system, to obtain feedback for adaptation and clarification of requirements. And the customers get to see early visible progress with the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 该系统在所有子系统中都已完全集成并稳定为基线内部版本。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The system, across all subsystems, has been completely integrated and stabilized as a baselined internal release.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                为简洁起见,跳过了许多结束迭代 1 和启动迭代 2 的活动,因为本演示的重点是对 OOA/D 的介绍。对跳过的无数活动的评论包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the interest of brevity, many activities concluding iteration-1 and initiating iteration-2 are skipped, since the emphasis of this presentation is an introduction to OOA/D. Comments on a few of the myriad activities that are skipped include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 迭代计划会议,用于决定在下一个迭代中要做什么、解决问题并确定主要任务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • An iteration planning meeting to decide what to work on in the next iteration, resolve questions, and identify major tasks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 在新迭代开始时,使用 UML 工具从上次迭代的源代码中对图表进行逆向工程(结果是 UP Design Model 的一部分)。这些可以在绘图仪上以大尺寸打印,并张贴在项目室的墙壁上,作为交流辅助工具,以说明下一次迭代的逻辑设计的起点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • At the start of the new iteration, use a UML tool to reverse engineer diagrams from the source code of the last iteration (the results are part of the UP Design Model). These can be printed in large size on a plotter and posted on the walls of the project room, as a communication aid to illustrate the starting point of the logical design for the next iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • UI 的可用性分析和工程设计正在进行中。对于许多系统的成功来说,这是一项非常重要的技能和活动。然而,这个主题是详细且非平凡的,超出了本书的范围。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Usability analysis and engineering for the UI is underway. This is an extraordinarily important skill and activity for the success of many systems. However, the subject is detailed and non-trivial, and outside the scope of this book.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 数据库建模和实施正在进行中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Database modeling and implementation is underway.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 另一个为期两天(例如)的需求研讨会举行,其中更多的用例以完全成型的格式编写。在细化过程中,虽然可能正在设计和实现 10% 的最危险的需求,但有一个并行活动来深入探索和定义系统 80% 的用例,即使这些需求中的大多数要到以后的迭代才会实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 参与者将包括第一次迭代中的一些开发人员(包括软件架构师),以便从实际快速构建一些软件中获得的见解(和困惑)来了解本次研讨会期间的调查和提问。没有什么比构建软件更能发现我们真正不知道的需求了,这是 UP 和迭代进化方法中的一个关键思想。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Another two-day (for example) requirements workshop occurs, in which more use cases are written in their fully dressed format. During elaboration, while perhaps 10% of the most risky requirements are being designed and implemented, there is a parallel activity to deeply explore and define perhaps 80% of the use cases for the system, even though most of these requirements won't be implemented until later iterations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Participants will include a few developers (including the software architect) from the first iteration, so that the investigation and questioning during this workshop is informed from the insights (and confusions) gained from actually quickly building some software. There's nothing like building software to discover what we really don't know about the requirementsthis is a key idea in the UP and iterative, evolutionary methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                案例研究中的简化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Simplifications in the Case Study

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在一个熟练的 UP 项目中,为早期迭代选择的需求是按风险和高业务价值组织的,以便及早识别和解决高风险问题。但是,如果此案例研究完全遵循该策略,则不可能帮助解释早期迭代中 OOA/D 的基本思想和原则。因此,一些许可是随着需求的优先级而采取的,更喜欢那些支持教育目标的,而不是项目风险目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In a skillful UP project, the requirements chosen for the early iterations are organized by risk and high business value, so that the high-risk issues are identified and resolved early. However, if this case study exactly followed that strategy, it would not be possible to help explain fundamental ideas and principles of OOA/D in the early iterations. Therefore, some license is taken with the prioritization of requirements, preferring those that support the educational goals, rather than project risk goals.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  24.2. 迭代 2 的要求和重点:对象设计和模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  24.2. Iteration-2 Requirements and Emphasis: Object Design and Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如前所述,对于这些案例研究,迭代 2 在很大程度上忽略了需求分析和领域分析,而是专注于具有职责和 GRASP 的对象设计,并应用了一些 GoF 设计模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As mentioned, for these case studies iteration-2 largely ignores requirements analysis and domain analysis, and focuses on object design with responsibilities and GRASP, and applying some GoF design patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  下一代 POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  NextGen POS 应用程序的迭代 2 处理了几个有趣的需求:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Iteration-2 of the NextGen POS application handles several interesting requirements:



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 支持第三方外部服务中的变体。例如,不同的税收计算器必须可连接到系统,并且每个计算器都有一个唯一的界面。不同的会计系统也是如此,依此类推。每个都将为核心常用功能提供不同的 API 和协议。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Support for variations in third-party external services. For example, different tax calculators must be connectable to the system, and each has a unique interface. Likewise with different accounting systems and so forth. Each will offer a different API and protocol for a core of common functions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 复杂的定价规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Complex pricing rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 当销售总额发生变化时刷新 GUI 窗口的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. A design to refresh a GUI window when the sale total changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这些要求将仅在 Process Sale 用例的场景上下文中考虑(对于此迭代)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  These requirements will only be considered (for this iteration) in the context of scenarios of the Process Sale use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,这些并不是新发现的要求;他们在成立时就被识别出来了。例如,原始 Process Sale 用例指示定价问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Please note that these are not newly discovered requirements; they were identified during inception. For example, the original Process Sale use case indicates the pricing problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 客户到达 POS 结账处,并携带要购买的商品和/或服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Customer arrives at a POS checkout with goods and/or services to purchase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. Cashier 告诉 System 创建一个新的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Cashier tells System to create a new sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 收银员输入商品标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. Cashier enters item identifier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7. 系统记录销售行项目并显示项目描述、价格和汇总。根据一组价格规则计算出的价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  8. System records sale line item and presents item description, price, and running total. Price calculated from a set of price rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此外,补充规范中的部分记录了 domain 规则的定价细节,并指出需要支持不同的外部系统:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Furthermore, sections in the Supplementary Specification record details of the domain rules for pricing, and indicate the need to support varying external systems:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  补充规格

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Supplementary Specification

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  接口

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  软件接口

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  对于大多数外部协作系统(税收计算器、会计、库存等),我们需要能够插入不同的系统,从而插入不同的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For most external collaborating systems (tax calculator, accounting, inventory, ... ) we need to be able to plug in varying systems and thus varying interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  域 (业务) 规则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Domain (Business) Rules

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  身份证

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ID

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  统治

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Rule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  多变性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Changeability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Source

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  规则 4

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  RULE4

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  购买者折扣规则。例子:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Purchaser discount rules. Examples:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  High.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  零售商政策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Retailer policy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  员工 20% 折扣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Employee20% off.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  每个零售商使用不同的规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Each retailer uses different rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  优惠顾客10% 折扣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preferred Customer10% off.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  老年人15% 折扣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Senior15% off.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  感兴趣域中的信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Information in Domains of Interest

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  定价

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Pricing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  除了域规则部分中描述的定价规则外,请注意,产品具有原价永久降价(可选)。商品的价格(进一步折扣之前)是永久降价价格(如果存在)。出于会计和税务原因,即使有永久的降价,组织也会保持原价。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In addition to the pricing rules described in the domain rules section, note that products have an original price, and optionally a permanent markdown price. A product's price (before further discounts) is the permanent markdown price, if present. Organizations maintain the original price even if there is a permanent markdown price, for accounting and tax reasons.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ...



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  跨迭代用例的增量开发

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  由于这些要求,我们在迭代 2 中重新审视了 Process Sale 用例,但实施了更多场景,以便系统逐步增长。通常会在多次迭代中处理同一用例的不同场景或功能,然后逐渐扩展系统以最终处理所需的所有功能。另一方面,简短的用例可以在一次迭代中完全实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Because of these requirements, we are revisiting the Process Sale use case in iteration-2, but implementing more scenarios, so that the system incrementally grows. It is common to work on varying scenarios or features of the same use case over several iterations and gradually extend the system to ultimately handle all the functionality required. On the other hand, short, simple use cases may be completely implemented within one iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  但是,不应将一个方案拆分为多个迭代;迭代应完成一个或多个端到端方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  However, one scenario should not be split across iterations; an iteration should complete one or more end-to-end scenarios.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  迭代 1 进行了简化,以便问题和解决方案不会过于复杂。同样,出于同样的原因,考虑了相对少量的附加功能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Iteration-1 made simplifications so that the problem and solution were not overly complex to explore. Once againfor the same reasona relatively small amount of additional functionality is considered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  垄断

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Monopoly



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Monopoly 应用程序第二次迭代的额外要求包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The additional requirements for the second iteration of the Monopoly application include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 同样,实现 Play Monopoly Game 用例的基本关键场景:玩家在棋盘的方格中移动。和以前一样,将游戏作为模拟运行,除了玩家数量之外,不需要用户输入。但是,在迭代 2 中,一些特殊的 square 规则适用。这些在以下几点中进行了描述...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Again, implement a basic, key scenario of the Play Monopoly Game use case: players moving around the squares of the board. And as before, run the game as a simulation requiring no user input, other than the number of players. However, in iteration-2 some of the special square rules apply. These are described in the following points…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 每个玩家在游戏开始时收到 1500 美元。认为游戏有无限数量的钱。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Each player receives $1500 at the beginning of the game. Consider the game to have an unlimited amount of money.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 当玩家降落在 Go 方格上时,玩家将获得 200 美元。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • When a player lands on the Go square, the player receives $200.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 当玩家降落在 Go-To-Jail 方格时,他们会移动到 Jail 方格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 然而,与完整的规则不同的是,他们很容易脱身。在下一轮,他们只需按照掷骰总数所示滚动和移动。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • When a player lands on the Go-To-Jail square, they move to the Jail square.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • However, unlike the complete rules, they get out easily. On their next turn, they simply roll and move as indicated by the roll total.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 当玩家降落在所得税方块上时,玩家支付最低 200 美元或其价值的 10%。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • When a player lands on the Income-Tax square, the player pays the minimum of $200 or 10% of their worth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    第 25 章.GRASP:更多具有职责的对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Chapter 25. GRASP: More Objects with Responsibilities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    运气是设计的残留物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Branch Rickey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Luck is the residue of design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Branch Rickey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 学习应用其余的 GRASP 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Learn to apply the remaining GRASP patterns.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以前,我们应用了五种 GRASP 模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Previously, we applied five GRASP patterns:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 信息专家、创建者、高内聚、低耦合和控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Information Expert, Creator, High Cohesion, Low Coupling, and Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      本章介绍了最后四种 GRASP 模式。他们是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The final four GRASP patterns are covered in this chapter. They are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 多态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Polymorphism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 间接

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Indirection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 纯制造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Pure Fabrication

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      一旦解释了这些,我们将拥有丰富且共享的词汇来讨论设计。随着一些 “Gang-of-Four” (GoF) 设计模式(如 Strategy 和 Abstract Factory)在后续章节中也被引入,这些词汇量将会增加。一个简短的句子,如“I suggest a Strategy generated from a Abstract Factory to support Protected Variations and low coupling on to <X>”,传达了有关设计的大量信息,因为模式名称简洁地传达了复杂的设计概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Once these have been explained, we will have a rich and shared vocabulary with which to discuss designs. And as some of the "Gang-of-Four" (GoF) design patterns (such as Strategy and Abstract Factory) are also introduced in subsequent chapters, that vocabulary will grow. A short sentence, such as "I suggest a Strategy generated from a Abstract Factory to support Protected Variations and low coupling with respect to <X>" communicates lots of information about the design, since pattern names tersely convey a complex design concept.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      后续章节介绍了其他有用的模式,并将它们应用于案例研究的第二次迭代的开发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Subsequent chapters introduce other useful patterns and apply them to the development of the second iteration of the case studies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        25.1. 多态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        25.1. Polymorphism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如何处理基于类型的备选方案?如何创建可插拔的软件组件?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        How handle alternatives based on type? How to create pluggable software components?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        基于类型的替代方案条件变化是程序中的一个基本主题。如果一个程序是使用 if-then-else 或 case 语句条件逻辑设计的,那么如果出现新的变化,它通常需要在许多地方修改 case logic。这种方法使得很难轻松地使用新的变体扩展程序,因为只要存在条件逻辑,就往往需要在多个地方进行更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Alternatives based on type Conditional variation is a fundamental theme in programs. If a program is designed using if-then-else or case statement conditional logic, then if a new variation arises, it requires modification of the case logicoften in many places. This approach makes it difficult to easily extend a program with new variations because changes tend to be required in several placeswherever the conditional logic exists.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        可插拔软件组件查看客户端-服务器关系中的组件,如何在不影响客户端的情况下将一个服务器组件替换为另一个服务器组件?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Pluggable software components Viewing components in client-server relationships, how can you replace one server component with another, without affecting the client?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        当相关的替代项或行为因类型(类)而异时,将行为使用多态操作的责任分配给行为变化的类型。[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        When related alternatives or behaviors vary by type (class), assign responsibility for the behaviorusing polymorphic operationsto the types for which the behavior varies.[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] 多态性有几个相关的含义。在此上下文中,当服务相似或相关时,它的意思是“为不同对象中的服务提供相同的名称”[Coad95]。不同的对象类型通常实现一个公共接口,或者在具有公共超类的实现层次结构中相关,但这取决于语言;例如,动态绑定语言(如 Smalltalk)不需要这样做。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] Polymorphism has several related meanings. In this context, it means "giving the same name to services in different objects" [Coad95] when the services are similar or related. The different object types usually implement a common interface or are related in an implementation hierarchy with a common superclass, but this is language-dependent; for example, dynamic binding languages such as Smalltalk do not require this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        推论: 不要测试对象的类型,并使用条件逻辑根据类型执行不同的替代项。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Corollary: Do not test for the type of an object and use conditional logic to perform varying alternatives based on type.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Examples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        NextGen 问题:如何支持第三方税收计算器?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        NextGen Problem: How Support Third-Party Tax Calculators?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 NextGen POS 应用程序中,必须支持多个外部第三方税收计算器(例如 Tax-Master 和 Good-As-Gold TaxPro);系统需要能够与不同的系统集成。每个税收计算器都有不同的接口,因此存在相似但不同的行为来适应每个外部固定接口或 API。一个产品可能支持原始 TCP 套接字协议,另一个产品可能提供 SOAP 接口,第三个产品可能提供 Java RMI 接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the NextGen POS application, there are multiple external third-party tax calculators that must be supported (such as Tax-Master and Good-As-Gold TaxPro); the system needs to be able to integrate with different ones. Each tax calculator has a different interface, so there is similar but varying behavior to adapt to each of these external fixed interfaces or APIs. One product may support a raw TCP socket protocol, another may offer a SOAP interface, and a third may offer a Java RMI interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        哪些对象应该负责处理这些不同的外部 tax calculator 接口?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        What objects should be responsible for handling these varying external tax calculator interfaces?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        由于计算器适应的行为因计算器的类型而异,因此通过多态性,我们应该将适应的责任分配给不同的计算器(或计算器适配器)对象本身,通过多态 getTaxes 操作实现(参见图 25.1)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Since the behavior of calculator adaptation varies by the type of calculator, by Polymorphism we should assign the responsibility for adaptation to different calculator (or calculator adapter) objects themselves, implemented with a polymorphic getTaxes operation (see Figure 25.1).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 25.1.适应不同外部税收计算器的多态性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这些计算器适配器对象不是外部计算器,而是表示外部计算器或计算器适配器的本地软件对象。通过向本地对象发送消息,最终将在其本机 API 中对外部计算器进行调用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        These calculator adapter objects are not the external calculators, but rather, local software objects that represent the external calculators, or the adapter for the calculator. By sending a message to the local object, a call will ultimately be made on the external calculator in its native API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        每个 getTaxes 方法都将 Sale 对象作为参数,以便计算器可以分析销售。每个 getTaxes 方法的实现将有所不同:TaxMasterAdapter 将使请求适应 Tax-Master 的 API,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Each getTaxes method takes the Sale object as a parameter, so that the calculator can analyze the sale. The implementation of each getTaxes method will be different: TaxMasterAdapter will adapt the request to the API of Tax-Master, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML请注意图 25.1 中的 interface 和 interface implementation 表示法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML Notice the interface and interface realization notation in Figure 25.1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        大富翁问题:如何针对不同的方形动作进行设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Monopoly Problem: How to Design for Different Square Actions?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        回顾一下,当玩家降落在 Go 方格上时,他们会收到 200 美元。登陆 Income Tax (所得税) 方块有不同的操作,依此类推。请注意,不同类型的方块有不同的规则。让我们回顾一下 Polymorphism 设计原则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To review, when a player lands on the Go square, they receive $200. There's a different action for landing on the Income Tax square, and so forth. Notice that there is a different rule for different types of squares. Let's review the Polymorphism design principle:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        当相关的替代项或行为因类型(类)而异时,将行为使用多态操作的责任分配给行为变化的类型。推论:不要测试对象的类型,并使用条件逻辑根据类型执行不同的替代方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        When related alternatives or behaviors vary by type (class), assign responsibility for the behaviorusing polymorphic operationsto the types for which the behavior varies. Corollary: Do not test for the type of an object and use conditional logic to perform varying alternatives based on type.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        从推论中,我们知道我们不应该使用 case logic(Java 或 C# 中的 switch 语句)进行设计,如以下伪代码所示:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        From the corollary, we know we should not design with case logic (a switch statement in Java or C#) as in the following pseudocode:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           // bad design
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SWITCH ON square.type
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CASE GoSquare: player receives $200
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CASE IncomeTaxSquare: player pays tax
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           // bad design
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SWITCH ON square.type
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CASE GoSquare: player receives $200
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        CASE IncomeTaxSquare: player pays tax
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        相反,该原则建议我们为行为变化的每种类型创建一个多态运算。它因类型 (类) RegularSquare、GoSquare 等而异。变化的操作是什么?这就是玩家降落在方格上时发生的情况。因此,多态运算的好名称是 landedOn 或一些变体。因此,通过多态性,我们将为具有不同 landedOn 职责的每种 square 创建一个单独的类,并在每种 square 中实现 landedOn 方法。图 25.2 说明了 static-view 类的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Rather, the principle advises us to create a polymorphic operation for each type for which the behavior varies. It varies for the types (classes) RegularSquare, GoSquare, and so on. What is the operation that varies? It's what happens when a player lands on a square. Thus, a good name for the polymorphic operation is landedOn or some variation. Therefore, by Polymorphism, we'll create a separate class for each kind of square that has a different landedOn responsibility, and implement a landedOn method in each. Figure 25.2 illustrates the static-view class design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 25.2.将多态性应用于垄断问题。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        应用 UML: 请注意,在图 25.2 中,{abstract} 关键字用于 landedOn 操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Applying UML: Notice in Figure 25.2 the use of the {abstract} keyword for the landedOn operation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        指南: 除非超类中有默认行为,否则请在超类中将多态操作声明为 {abstract}

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Guideline: Unless there is a default behavior in the superclass, declare a polymorphic operation in the superclass to be {abstract}.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        剩下的有趣问题是动态设计:交互图应该如何发展?什么对象应该将 landedOn 消息发送到玩家着陆的方格?由于 Player 软件对象已经知道其位置方格(它所在的位置),因此根据 Low Coupling 和 Expert 的原理,类 Player 是发送消息的不错选择,因为 Player 已经可以看到正确的方格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The remaining interesting problem is the dynamic design: How should the interaction diagrams evolve? What object should send the landedOn message to the square that a player lands on? Since a Player software object already knows its location square (the one it landed on), then by the principles of Low Coupling and by Expert, class Player is a good choice to send the message, as a Player already has visibility to the correct square.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        当然,此消息应在 takeTurn 方法的末尾发送。请查看第 355 页的迭代 1 takeTurn 设计,了解我们的起点。图 25.3图 25.4 说明了不断发展的动态设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Naturally, this message should be sent at the end of the takeTurn method. Please review the iteration-1 takeTurn design on p. 355 to see our starting point. Figure 25.3 and Figure 25.4 illustrate the evolving dynamic design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 25.3.应用多态性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 25.4.GoSquare 案例。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        应用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Applying UML:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML 帧,第 235

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML frames p. 235



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 请注意图 25.3图 25.4 中在绘制 UML 草图时在单独的图表中显示多态情况的非正式方法。尤其是在使用 UML 工具时,另一种方法是使用 sdref 帧。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Notice in Figure 25.3 and Figure 25.4 the informal approach to showing the polymorphic cases in separate diagrams when sketching UML. An alternativeespecially when using a UML toolis to use sd and ref frames.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 请注意,在图 25.3 中,Player 对象被标记为 'p',因此在 landedOn 消息中,我们可以在参数列表中引用该对象。(您将在图 25.4 中看到,SquarePlayer 具有参数可见性是很有用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Notice in Figure 25.3 that the Player object is labeled 'p' so that in the landedOn message we can refer to that object in the parameter list. (You will see in Figure 25.4 that it is useful for the Square to have parameter visibility to the Player.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 请注意,在图 25.3 中,Square 对象被标记为 loc('location' 的缩写),这与 getSquare 消息中的返回值变量的标签相同。这意味着它们是同一个对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Notice in Figure 25.3 that the Square object is labeled loc (short for 'location') and this is the same label as the return value variable in the getSquare message. This implies they are the same object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        让我们根据 GRASP 和设计问题来考虑每个多态情况:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Let's consider each of the polymorphic cases in terms of GRASP and the design issues:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • GoSquare (戈方)参见图 25.4。通过低代表性差距,玩家应该知道它的现金。因此,通过 Expert,它应该发送一条 addCash 消息。因此,方块需要对 Player 可见,以便它可以发送消息;因此,Player 在 landedOn 消息中作为参数 'p' 传递,以实现参数可见性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • GoSquare See Figure 25.4. By low representational gap, the Player should know its cash. Therefore, by Expert, it should be sent an addCash message. Thus the square needs visibility to the Player so it can send the message; consequently, the Player is passed as a parameter 'p' in the landedOn message to achieve parameter visibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 常规方块参见图 25.5。在这种情况下,什么都不会发生。我已经非正式地标记了该图以表明这一点,尽管也可以使用 UML 注释框。在代码中,此方法的主体将是空的,有时称为 NO-OP(无操作)方法。请注意,要使多态性的魔力发挥作用,我们需要使用这种方法来避免特殊情况逻辑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 25.5.RegularSquare 情况。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • RegularSquare See Figure 25.5. In this case, nothing happens. I've informally labeled the diagram to indicate this, though a UML note box could be used as well. In code, the body of this method will be emptysometimes called a NO-OP (no operation) method. Note that to make the magic of polymorphism work, we need to use this approach to avoid special case logic.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Figure 25.5. The RegularSquare case.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 所得税广场参见图 25.6。我们需要计算玩家净资产的 10%。通过低代表性差距和专家,谁应该知道这一点?玩家。因此,方格询问玩家的价值,然后扣除适当的金额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 25.6.IncomeTaxSquare 案。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • IncomeTaxSquare See Figure 25.6. We need to calculate 10% of the player's net worth. By low representational gap and by Expert, who should know this? The Player. Thus the square asks for the player's worth, and then deducts the appropriate amount.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Figure 25.6. The IncomeTaxSquare case.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • GoToJailSquare参见图 25.7。简单地说,必须更改 Player 的位置。通过 Expert,它应该会收到 setLocation 消息。GoToJailSquare 可能会使用引用 JailSquare 的属性进行初始化,以便它可以将此方块作为参数传递给 Player

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 25.7.GoToJailSquare 案。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • GoToJailSquare See Figure 25.7. Simply, the Player's location must be changed. By Expert, it should receive a setLocation message. Probably, the GoToJailSquare will be initialized with an attribute referencing the JailSquare, so that it can pass this square as a parameter to the Player.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Figure 25.7. The GoToJailSquare case.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML 作为草图: 请注意,在图 25.4 中,垂直生命线绘制为实线,而不是传统的虚线。这在手绘草图时更方便。此外,UML 2 允许任何一种格式,尽管无论如何,在绘制草图时,与正确的 UML 的一致性并不那么重要,重要的是参与者相互理解。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML as Sketch: Notice in Figure 25.4 that the vertical lifeline is drawn as a solid line, rather than the traditional dashed line. This is more convenient when hand sketching. Furthermore, UML 2 allows either formatalthough in any event conformance to correct UML is not so important when sketching, only that the participants understand each other.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        改进耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Improving the Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        作为一个小的 OO 设计改进,请注意在第 357 页的图 18.25 中,迭代 1 的 Piece 记住了正方形位置,但 Player 没有,因此 Player 必须从 Piece 中提取位置(将 getSquare 消息发送到 Board),然后将新位置重新分配给 Piece。这是一个薄弱的设计点,在这个迭代中,当 Player 还必须将 landedOn 消息发送到它的 Square 时,它会变得更弱。为什么?它有什么问题?答案:耦合问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As a small OO design refinement, notice in Figure 18.25 on p. 357 for iteration-1 that the Piece remembers the square location but the Player does not, and thus the Player must extract the location from the Piece (to send the getSquare message to the Board), and then re-assign the new location to the Piece. That's a weak design point, and in this iteration, when the Player must also send the landedOn message to its Square, it becomes even weaker. Why? What's wrong with it? Answer: Problems in coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        显然,Player 需要永久了解它自己的 Square 位置对象而不是 Piece,因为 Player 一直在与它的 Square 协作。您应该将此视为改进耦合的重构机会,当对象 A 始终需要对象 B 中的数据时,这意味着 1) 对象 A 应该保存该数据,或者 2) 对象 B 应该负责(由 Expert 而不是对象 A)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Clearly the Player needs to permanently know its own Square location object rather than the Piece, since the Player keeps collaborating with its Square. You should see this as a refactoring opportunity to improve couplingwhen object A keeps needing the data in object B it implies either 1) object A should hold that data, or 2) object B should have the responsibility (by Expert) rather than object A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        因此,在迭代 2 中,我改进了设计,以便 Player 而不是 Piece 知道它的方格;这反映在图 25.2 的 DCD 和图 25.3 的交互图中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Therefore, in iteration-2 I've refined the design so that the Player rather than the Piece knows its square; this is reflected in both the DCD of Figure 25.2 and the interaction diagram of Figure 25.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        事实上,人们甚至可以质疑 Piece 是否是设计模型中的有用对象。在现实世界中,板上的一个小塑料片是人类的有用代理,因为我们很大,会去厨房喝冰镇啤酒!但在软件中,Player 对象(是一个很小的软件 blob)可以扮演 Piece 的角色。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In fact, one can even question if the Piece is a useful object in the Design Model. In the real world, a little plastic piece sitting on the board is a useful proxy for a human, because we're big and go to the kitchen for cold beer! But in software, the Player object (being a tiny software blob) can fulfill the role of the Piece.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多态性是设计如何组织系统以处理类似变化的基本原则。基于 Polymorphism 分配职责的设计可以轻松扩展以处理新的变体。例如,添加具有自己的多态 getTaxes 方法的新计算器适配器类对现有设计的影响很小。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Polymorphism is a fundamental principle in designing how a system is organized to handle similar variations. A design based on assigning responsibilities by Polymorphism can be easily extended to handle new variations. For example, adding a new calculator adapter class with its own polymorphic getTaxes method will have minor impact on the existing design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        指南:何时使用界面进行设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Guideline: When to Design with Interfaces?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多态性意味着在大多数 OO 语言中存在抽象超类或接口。何时应考虑使用接口?一般的答案是,当你想支持多态性而不被委身于特定的类层次结构时,引入一个。如果在没有接口的情况下使用抽象超类 AC,则任何新的多态解决方案都必须是 AC 的子类,这在 Java 和 C# 等单继承语言中非常有限。根据经验,如果存在具有抽象超类 C1 的类层次结构,可以考虑制作一个与 C1 的公共方法签名相对应的接口 I1,然后声明 C1 来实现 I1 接口。然后,即使没有直接的动机避免在 C1 下进行新的多态解决方案的子类化,对于未知的未来情况,也有一个灵活的进化点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Polymorphism implies the presence of abstract superclasses or interfaces in most OO languages. When should you consider using an interface? The general answer is to introduce one when you want to support polymorphism without being committed to a particular class hierarchy. If an abstract superclass AC is used without an interface, any new polymorphic solution must be a subclass of AC, which is very limiting in single-inheritance languages such as Java and C#. As a rule-of-thumb, if there is a class hierarchy with an abstract superclass C1, consider making an interface I1 that corresponds to the public method signatures of C1, and then declare C1 to implement the I1 interface. Then, even if there is no immediate motivation to avoid subclassing under C1 for a new polymorphic solution, there is a flexible evolution point for unknown future cases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有时,开发人员设计具有接口和多态性的系统,用于针对未知的可能变体进行推测性的“面向未来”。如果变异点肯定是由直接或非常可能的变异性驱动的,那么通过多态性增加灵活性的努力当然是合理的。但是需要批判性评估,因为在变化点上花费不必要的精力来使具有多态性的设计适应未来,这实际上是不可能的,也永远不会真正出现。在投资于提高灵活性之前,请对可变性的真实可能性保持现实。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Sometimes, developers design systems with interfaces and polymorphism for speculative "future-proofing" against an unknown possible variation. If the variation point is definitely motivated by an immediate or very probable variability, then the effort of adding the flexibility through polymorphism is of course rational. But critical evaluation is required, because it is not uncommon to see unnecessary effort being applied to future-proofing a design with polymorphism at variation points that in fact are improbable and will never actually arise. Be realistic about the true likelihood of variability before investing in increased flexibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 新变体所需的扩展很容易添加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Extensions required for new variations are easy to add.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 可以在不影响客户端的情况下引入新的实施。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • New implementations can be introduced without affecting clients.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 本书将讨论的许多流行的 GoF 设计模式 [GHJV95] 都依赖于多态性,包括 Adapter、Command、Composite、Proxy、State 和 Strategy。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A number of popular GoF design patterns [GHJV95], which will be discussed in this book, rely on polymorphism, including Adapter, Command, Composite, Proxy, State, and Strategy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        也称为;似

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Also Known As; Similar To

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        选择消息,不要问“什么种类?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Choosing Message, Don't Ask "What Kind?"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          25.2. 纯制造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          25.2. Pure Fabrication

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当您不想违反 High Cohesion 和 Low Coupling 或其他目标,但 Expert 提供的解决方案(例如)不合适时,应该由哪个对象负责?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          What object should have the responsibility, when you do not want to violate High Cohesion and Low Coupling, or other goals, but solutions offered by Expert (for example) are not appropriate?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          面向对象设计有时的特点是将实际问题域中的概念表示实现为软件类,以降低表示差距;例如,SaleCustomer 类。然而,在许多情况下,仅将职责分配给域层软件类会导致内聚或耦合不良或重用潜力低等问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Object-oriented designs are sometimes characterized by implementing as software classes representations of concepts in the real-world problem domain to lower the representational gap; for example a Sale and Customer class. However, there are many situations in which assigning responsibilities only to domain layer software classes leads to problems in terms of poor cohesion or coupling, or low reuse potential.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将一组高度内聚的职责分配给一个人工的或方便的类,该类不代表一个问题域概念的虚构,以支持高内聚、低耦合和重用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign a highly cohesive set of responsibilities to an artificial or convenience class that does not represent a problem domain conceptsomething made up, to support high cohesion, low coupling, and reuse.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这样的课程是想象的捏造。理想情况下,分配给此制造的职责支持高内聚和低耦合,因此制造的设计非常干净,或者纯粹因此是纯制造。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Such a class is a fabrication of the imagination. Ideally, the responsibilities assigned to this fabrication support high cohesion and low coupling, so that the design of the fabrication is very clean, or purehence a pure fabrication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          最后,在英语中,pure fabrication 是一个成语,意思是编造一些东西,我们在绝望时这样做!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Finally, in English pure fabrication is an idiom that implies making something up, which we do when we're desperate!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          例子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Examples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          NextGen 问题:在数据库中保存销售对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          NextGen Problem: Saving a Sale Object in a Database

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          例如,假设需要支持将 Sale 实例保存在关系数据库中。根据 Information Expert,有理由将此责任分配给 Sale 类本身,因为销售具有需要保存的数据。但请考虑以下含义:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          For example, suppose that support is needed to save Sale instances in a relational database. By Information Expert, there is some justification to assign this responsibility to the Sale class itself, because the sale has the data that needs to be saved. But consider the following implications:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 该任务需要相对大量的支持面向数据库的操作,这些操作与 sale-ness 的概念无关,因此 Sale 类变得不连贯。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The task requires a relatively large number of supporting database-oriented operations, none related to the concept of sale-ness, so the Sale class becomes incohesive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Sale 类必须与关系数据库接口(比如 Java 技术中的 JDBC)耦合,因此它的耦合性会上升。而且耦合甚至不是到另一个域对象,而是到一种特定类型的数据库接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The Sale class has to be coupled to the relational database interface (such as JDBC in Java technologies), so its coupling goes up. And the coupling is not even to another domain object, but to a particular kind of database interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 在关系数据库中保存对象是一项非常通用的任务,许多类都需要支持。将这些职责放在 Sale 类中意味着在执行相同操作的其他类中将存在糟糕的重用或大量重复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Saving objects in a relational database is a very general task for which many classes need support. Placing these responsibilities in the Sale class suggests there is going to be poor reuse or lots of duplication in other classes that do the same thing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因此,即使 Sale 凭借 Information Expert 将自身保存在数据库中是一个合乎逻辑的候选者,但它导致了一个低内聚、高耦合和低重用潜力的设计,正是那种需要编造的绝望情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Thus, even though Sale is a logical candidate by virtue of Information Expert to save itself in a database, it leads to a design with low cohesion, high coupling, and low reuse potentialexactly the kind of desperate situation that calls for making something up.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          一个合理的解决方案是创建一个新类,该类专门负责将对象保存在某种持久性存储介质(例如关系数据库)中;将其称为 PersistentStorage[2] 这个类是纯粹的捏造,是想象的虚构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A reasonable solution is to create a new class that is solely responsible for saving objects in some kind of persistent storage medium, such as a relational database; call it the PersistentStorage.[2] This class is a Pure Fabricationa figment of the imagination.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [2] 在真正的持久化框架中,要创建合理的设计,最终需要不止一个纯制造类。此对象将是大量后端帮助程序对象的前端 Facade。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [2] In a real persistence framework, more than a single pure fabrication class is ultimately necessary to create a reasonable design. This object will be a front-end facade on to a large number of back-end helper objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意名称:PersistentStorage。这是一个可以理解的概念,但 “持久存储” 这个名称或概念并不是在 Domain Model 中找到的。如果设计师问商店里的业务人员,“您是否使用持久存储对象?他们了解 “sale” 和 “payment” 等概念。PersistentStorage 不是一个领域概念,而是为了方便软件开发人员而编造或捏造的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Notice the name: PersistentStorage. This is an understandable concept, yet the name or concept "persistent storage" is not something one would find in the Domain Model. And if a designer asked a business-person in a store, "Do you work with persistent storage objects?" they would not understand. They understand concepts such as "sale" and "payment." PersistentStorage is not a domain concept, but something made up or fabricated for the convenience of the software developer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          此 Pure Fabrication 解决了以下设计问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This Pure Fabrication solves the following design problems:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Sale 保持了良好的设计,具有高内聚力和低耦合性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The Sale remains well-designed, with high cohesion and low coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • PersistentStorage 类本身是相对内聚的,其唯一目的是在持久性存储介质中存储或插入对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The PersistentStorage class is itself relatively cohesive, having the sole purpose of storing or inserting objects in a persistent storage medium.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • PersistentStorage 类是一个非常通用且可重用的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The PersistentStorage class is a very generic and reusable object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在此示例中,创建纯制造正是需要使用它们来消除基于 Expert 的不良设计、内聚力和耦合性差、具有更大重用潜力的良好设计的情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Creating a pure fabrication in this example is exactly the situation in which their use is called foreliminating a bad design based on Expert, with poor cohesion and coupling, with a good design in which there is greater potential for reuse.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,与所有 GRASP 模式一样,重点是应将责任放在何处。在此示例中,职责从 Sale 类(由 Expert 激励)转移到 Pure Fabrication。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that, as with all the GRASP patterns, the emphasis is on where responsibilities should be placed. In this example the responsibilities are shifted from the Sale class (motivated by Expert) to a Pure Fabrication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          垄断问题:处理骰子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Monopoly Problem: Handling the Dice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在重构章节中,我使用了掷骰子行为(掷骰子总数并求和)的示例,在 Player.takeTurn 方法中应用 Extract 方法(第 391 页)。在示例的末尾,我还提到重构的解决方案本身并不理想,稍后将提出更好的解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the refactoring chapter, I used the example of dice rolling behavior (rolling and summing the dice totals) to apply Extract Method (p. 391) in the Player.takeTurn method. At the end of the example I also mentioned that the refactored solution itself was not ideal, and a better solution would be presented later.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在当前设计中,玩家掷出所有骰子并对总数求和。骰子是非常通用的对象,可以在许多游戏中使用。通过将这种滚动和求和责任放在 Monopoly 游戏玩家中,求和服务不会泛化为在其他游戏中使用。另一个弱点:不可能简单地询问当前的骰子总数而不再次掷骰子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In the current design, the Player rolls all the dice and sums the total. Dice are very general objects, usable in many games. By putting this rolling and summing responsibility in a Monopoly game Player, the summing service is not generalized for use in other games. Another weakness: It is not possible to simply ask for the current dice total without rolling the dice again.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          但是,选择受 Monopoly 游戏域模型启发的任何其他对象都会导致相同的问题。这导致我们来到 Pure Fabricationmake something up 以方便地提供相关服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          But, choosing any other object inspired from the Monopoly game domain model leads to the same problems. And that leads us to Pure Fabricationmake something up to conveniently provide related services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          虽然大富翁中没有骰子杯,但许多游戏确实使用骰子杯,在其中摇晃所有骰子并将它们掷到桌子上。因此,我提出了一个名为 Cup 的 Pure Fabrication(请注意,我仍在尝试使用类似的领域相关词汇)来容纳所有骰子,掷出它们,并知道它们的总数。新设计如图 25.8图 25.9 所示。Cup 包含许多 Die 对象的集合。当一个人向 Cup 发送掷骰消息时,它会向其所有骰子发送掷消息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Although there is no cup for the dice in Monopoly, many games do use a dice cup in which one shakes all the dice and rolls them onto a table. Therefore, I propose a Pure Fabrication called Cup (notice that I'm still trying to use similar domain-relevant vocabulary) to hold all the dice, roll them, and know their total. The new design is shown in Figure 25.8 and Figure 25.9. The Cup holds a collection of many Die objects. When one sends a roll message to a Cup, it sends a roll message to all its dice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 25.8.杯的 DCD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 25.9.在大富翁游戏中使用杯子



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          对象的设计大致可分为两组:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The design of objects can be broadly divided into two groups:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. 那些通过表征分解选择的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. Those chosen by representational decomposition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. 那些通过行为分解选择的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. Those chosen by behavioral decomposition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          例如,软件类(如 Sale)的创建是通过表示分解实现的;Software 类与域中的事物相关或表示该 Domain。表示分解是对象设计中的一种常见策略,支持低表示差距的目标。但有时,我们希望通过对行为进行分组或通过算法来分配职责,而不必担心创建具有与实际域概念相关的名称或用途的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          For example, the creation of a software class such as Sale is by representational decomposition; the software class is related to or represents a thing in a domain. Representational decomposition is a common strategy in object design and supports the goal of low representational gap. But sometimes, we desire to assign responsibilities by grouping behaviors or by algorithm, without any concern for creating a class with a name or purpose that is related to a real-world domain concept.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          一个很好的例子是 “algorithm” 对象,比如 TableOfContentsGenerator,它的目的是(令人惊讶地)生成一个目录,它是由开发人员作为帮助程序或便利类创建的,无需担心从书籍和文档的领域词汇表中选择一个名称。它作为开发人员构思的一个便利类存在,用于将一些相关的行为或方法组合在一起,因此受到行为分解的激励。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A good example is an "algorithm" object such as a TableOfContentsGenerator, whose purpose is (surprise!) to generate a table of contents and was created as a helper or convenience class by a developer, without any concern for choosing a name from the domain vocabulary of books and documents. It exists as a convenience class conceived by the developer to group together some related behavior or methods, and is thus motivated by behavioral decomposition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          相比之下,名为 TableOfContents 的软件类的灵感来自表示分解,并且应该包含与我们的真实域概念一致的信息(例如章节名称)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          To contrast, a software class named TableOfContents is inspired by representational decomposition, and should contain information consistent with our concept of the real domain (such as chapter names).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将类标识为 Pure Fabrication 并不重要。这是一个教育概念,用于传达以下一般思想:一些软件类的灵感来自领域的表示,而有些软件类只是为了方便对象设计人员而“编造”的。这些便利类通常旨在将一些常见行为组合在一起,因此受到行为分解而不是表示分解的启发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Identifying a class as a Pure Fabrication is not critical. It's an educational concept to communicate the general idea that some software classes are inspired by representations of the domain, and some are simply "made up" as a convenience for the object designer. These convenience classes are usually designed to group together some common behavior, and are thus inspired by behavioral rather than representational decomposition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          换句话说,Pure Fabrication 通常是根据相关功能进行分区的,因此它是一种以功能为中心的或行为对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Said another way, a Pure Fabrication is usually partitioned based on related functionality, so it is a kind of function-centric or behavioral object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          许多现有的面向对象设计模式都是纯捏造的示例:Adapter、Strategy、Command 等 [GHJV95]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Many existing object-oriented design patterns are examples of Pure Fabrications: Adapter, Strategy, Command, and so on [GHJV95].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          最后值得重申的评论是:有时 Information Expert 提供的解决方案并不可取。即使对象由于拥有与责任相关的大量信息而成为责任的候选者,但在其他方面,它的选择会导致糟糕的设计,通常是由于内聚或耦合问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          As a final comment worth reiterating: Sometimes a solution offered by Information Expert is not desirable. Even though the object is a candidate for the responsibility by virtue of having much of the information related to the responsibility, in other ways, its choice leads to a poor design, usually due to problems in cohesion or coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 之所以支持 High Cohesion,是因为职责被分解到一个细粒度的类中,该类只关注一组非常具体的相关任务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • High Cohesion is supported because responsibilities are factored into a fine-grained class that only focuses on a very specific set of related tasks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 重用的可能性可能会增加,因为存在细粒度的 Pure Fabrication 类,这些类的职责在其他应用程序中具有适用性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Reuse potential may increase because of the presence of fine-grained Pure Fabrication classes whose responsibilities have applicability in other applications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          对象设计新手和更熟悉软件功能分解或组织软件的用户有时会过度使用行为分解为 Pure Fabrication 对象。夸张地说,函数只是成为对象。创建 “function” 或 “algorithm” 对象本身并没有错,但它需要与使用表示分解进行设计的能力相平衡,例如应用 Information Expert 的能力,以便像 Sale 这样的表示类也具有责任。Information Expert 支持将职责与知道这些职责所需信息的对象共置的目标,这往往支持较低的耦合。如果过度使用,Pure Fabrication 可能会导致太多行为对象,这些对象的责任与实现它们所需的信息在同一位置,这可能会对耦合产生不利影响。通常的症状是对象中的大多数数据都被传递给其他对象以对其进行推理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Behavioral decomposition into Pure Fabrication objects is sometimes overused by those new to object design and more familiar with decomposing or organizing software in terms of functions. To exaggerate, functions just become objects. There is nothing inherently wrong with creating "function" or "algorithm" objects, but it needs to be balanced with the ability to design with representational decomposition, such as the ability to apply Information Expert so that a representational class such as Sale also has responsibilities. Information Expert supports the goal of co-locating responsibilities with the objects that know the information needed for those responsibilities, which tends to support lower coupling. If overused, Pure Fabrication could lead to too many behavior objects that have responsibilities not co-located with the information required for their fulfillment, which can adversely affect coupling. The usual symptom is that most of the data inside the objects is being passed to other objects to reason with it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          相关模式和原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Related Patterns and Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Low Coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 高内聚力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • High Cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Pure Fabrication 通常承担域类的职责,该域类将根据 Expert 模式分配这些职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • A Pure Fabrication usually takes on responsibilities from the domain class that would be assigned those responsibilities based on the Expert pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 所有 GoF 设计模式 [GHJV95],例如 Adapter、Command、Strategy 等,都是纯制造。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • All GoF design patterns [GHJV95], such as Adapter, Command, Strategy, and so on, are Pure Fabrications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 几乎所有其他设计模式都是纯制造。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Virtually all other design patterns are Pure Fabrications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            25.3. 间接

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            25.3. Indirection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在哪里分配责任,以避免两个(或多个)事物之间的直接耦合?如何解耦对象,以便支持低耦合并保持更高的重用潜力?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Where to assign a responsibility, to avoid direct coupling between two (or more) things? How to de-couple objects so that low coupling is supported and reuse potential remains higher?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            将责任分配给一个中间对象,以便在其他组件或服务之间进行调解,以便它们不会直接耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Assign the responsibility to an intermediate object to mediate between other components or services so that they are not directly coupled.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            中介在其他组件之间创建间接性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The intermediary creates an indirection between the other components.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Examples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            TaxCalculatorAdapter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            TaxCalculatorAdapter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            这些对象充当外部税收计算器的中介。通过多态性,它们为内部对象提供了一致的接口,并隐藏了外部 API 中的变体。通过添加间接级别和添加多态性,适配器对象可以保护内部设计免受外部接口变化的影响(参见图 25.10)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            These objects act as intermediaries to the external tax calculators. Via polymorphism, they provide a consistent interface to the inner objects and hide the variations in the external APIs. By adding a level of indirection and adding polymorphism, the adapter objects protect the inner design against variations in the external interfaces (see Figure 25.10).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 25.10.通过适配器间接寻址。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            应用 UML: 请注意外部 TaxMaster 远程服务应用程序在图 25.10 中的建模方式:它标有 «actor» 关键字,表明它是 NextGen 系统的外部软件组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Applying UML: Notice how the external TaxMaster remote service application is modeled in Figure 25.10: It's labeled with the «actor» keyword to indicate it's an external software component to our NextGen system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            PersistentStorage (持久存储)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            PersistentStorage

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            通过引入 PersistentStorage 类将 Sale 与关系数据库服务解耦的 Pure Fabrication 示例也是分配责任以支持 Incircuit 的示例。PersistentStorage 充当 Sale 和数据库之间的中介。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Pure Fabrication example of decoupling the Sale from the relational database services through the introduction of a PersistentStorage class is also an example of assigning responsibilities to support Indirection. The PersistentStorage acts as a intermediary between the Sale and the database.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            “计算机科学中的大多数问题都可以通过另一个层次的间接来解决”是一句古老的格言,与面向对象的设计特别相关。[3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            "Most problems in computer science can be solved by another level of indirection" is an old adage with particular relevance to object-oriented designs. [3]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] 大卫·惠勒 (David Wheeler) 著。请注意还有一句反格言:“大多数性能问题都可以通过去除另一层间接来解决!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] By David Wheeler. Note there is also the counter-adage: "Most problems in performance can be solved by removing another layer of indirection!"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            正如许多现有的设计模式是 Pure Fabrication 的特化一样,许多也是 Incircuit 的特化。Adapter、Facade 和 Observer 是示例 [GHJV95]。此外,由于 Indirection(间接性),会生成许多 Pure Fabrications(纯制造)。In间接性的动机通常是低耦合;添加中介以解耦其他组件或服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Just as many existing design patterns are specializations of Pure Fabrication, many are also specializations of Indirection. Adapter, Facade, and Observer are examples [GHJV95]. In addition, many Pure Fabrications are generated because of Indirection. The motivation for Indirection is usually Low Coupling; an intermediary is added to decouple other components or services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 组件之间的耦合较低。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Lower coupling between components.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            相关模式和原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Related Patterns and Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Low Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 许多 GoF 模式,例如 Adapter、Bridge、Facade、Observer 和 Mediator [GHJV95]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Many GoF patterns, such as Adapter, Bridge, Facade, Observer, and Mediator [GHJV95].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 许多间接中介是纯粹的捏造。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Many Indirection intermediaries are Pure Fabrications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              25.4. 受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              25.4. Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如何设计对象、子系统和系统,以便这些元素的变化或不稳定性不会对其他元素产生不良影响?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How to design objects, subsystems, and systems so that the variations or instability in these elements does not have an undesirable impact on other elements?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              确定预测变化或不稳定性的点;分配职责以围绕它们创建稳定的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注: 术语“interface” 在最广泛的访问视图中使用;它不仅仅指 Java 接口之类的东西。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Note: The term "interface" is used in the broadest sense of an access view; it does not literally only mean something like a Java interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,先验的外部税计算器问题及其使用 Polymorphism 的解说明了 Protected Variations (图 25.1)。不稳定或变化的点是外部税收计算器的不同接口或 API。POS 系统需要能够与许多现有的税收计算器系统集成,并且还需要与未来尚不存在的第三方计算器集成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, the prior external tax calculator problem and its solution with Polymorphism illustrate Protected Variations (Figure 25.1). The point of instability or variation is the different interfaces or APIs of external tax calculators. The POS system needs to be able to integrate with many existing tax calculator systems, and also with future third-party calculators not yet in existence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              通过添加间接级别、接口以及将多态性与各种 ITaxCalculatorAdapter 实现结合使用,可以在系统内实现对外部 API 变化的保护。内部对象与稳定的界面协作;各种 adapter 实现对外部系统隐藏了变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              By adding a level of indirection, an interface, and using polymorphism with various ITaxCalculatorAdapter implementations, protection within the system from variations in external APIs is achieved. Internal objects collaborate with a stable interface; the various adapter implementations hide the variations to the external systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              讨论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discussion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这是软件设计的一个非常重要的基本原则!bookdata 封装、多态性、数据驱动设计、接口、虚拟机、配置文件、操作系统等中的几乎所有软件或架构设计技巧都是 Protected Variations 的专业化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is a very important, fundamental principle of software design! Almost every software or architectural design trick in bookdata encapsulation, polymorphism, data-driven designs, interfaces, virtual machines, configuration files, operating systems, and much moreis a specialization of Protected Variations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              受保护变体 (PV) 最初由 Cockburn 在 [VCK96] 中作为命名模式发布,尽管这个非常基本的设计原则已经以各种术语存在了几十年,例如术语信息隐藏 [Parnas72]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Protected Variations (PV) was first published as a named pattern by Cockburn in [VCK96], although this very fundamental design principle has been around for decades under various terms, such as the term information hiding [Parnas72].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              受保护变体驱动的机制

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Mechanisms Motivated by Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV 是激励编程和设计中的大多数机制和模式的根本原则,以提供灵活性并防止数据、行为、硬件、软件组件、操作系统等的变化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV is a root principle motivating most of the mechanisms and patterns in programming and design to provide flexibility and protection from variationsvariations in data, behavior, hardware, software components, operating systems, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在某种程度上,开发人员或架构师的成熟可以从他们对实现 PV 的更广泛的机制的不断了解中看出,他们能够选择值得参加的适当 PV 战斗,以及他们选择合适的 PV 解决方案的能力。在早期阶段,人们学习了数据封装、接口和 polymorphismall 核心机制来实现 PV。之后,人们学习了基于规则的语言、规则解释器、反射和元数据设计、虚拟机等技术,所有这些都可以应用于防止某些变化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              At one level, the maturation of a developer or architect can be seen in their growing knowledge of ever-wider mechanisms to achieve PV, to pick the appropriate PV battles worth fighting, and their ability to choose a suitable PV solution. In the early stages, one learns about data encapsulation, interfaces, and polymorphismall core mechanisms to achieve PV. Later, one learns techniques such as rule-based languages, rule interpreters, reflective and metadata designs, virtual machines, and so forthall of which can be applied to protect against some variation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              核心保护变体机制

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              数据封装、接口、多态性、间接性和标准都由 PV 驱动。请注意,虚拟机和操作系统等组件是实现 PV 的间接传入的复杂示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Data encapsulation, interfaces, polymorphism, indirection, and standards are motivated by PV. Note that components such as virtual machines and operating systems are complex examples of indirection to achieve PV.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              数据驱动设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              数据驱动设计涵盖了一系列广泛的技术,包括从外部源读取代码、值、类文件路径、类名等,以便在运行时以某种方式更改系统的行为或以某种方式“参数化”系统。其他变体包括样式表、对象关系映射的元数据、属性文件、在窗口布局中读取等等。通过外部化变体、读入变体并使用它进行推理,可以保护系统免受数据、元数据或声明性变体的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Data-driven designs cover a broad family of techniques including reading codes, values, class file paths, class names, and so forth, from an external source in order to change the behavior of, or "parameterize" a system in some way at run-time. Other variants include style sheets, metadata for object-relational mapping, property files, reading in window layouts, and much more. The system is protected from the impact of data, metadata, or declarative variations by externalizing the variant, reading it in, and reasoning with it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              服务查询

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              服务查找包括使用命名服务(例如,Java 的 JNDI)或交易者来获取服务(例如,Java 的 Jini 或用于 Web 服务的 UDDI)等技术。使用 lookup 服务的 stable 接口,可以保护 Client 端免受服务位置变化的影响。这是数据驱动设计的一个特例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Service lookup includes techniques such as using naming services (for example, Java's JNDI) or traders to obtain a service (for example, Java's Jini, or UDDI for Web services). Clients are protected from variations in the location of services, using the stable interface of the lookup service. It is a special case of data-driven design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              解释器驱动的设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              解释器驱动的设计包括执行从外部源读取的规则的规则解释器、读取和运行程序的脚本或语言解释器、虚拟机、执行网络的神经网络引擎、读取约束集并进行推理的约束逻辑引擎等。这种方法允许通过外部 logic 表达式更改或参数化系统的行为。通过外部化 logic、读入 logic 并使用 interpreter 来保护系统免受 logic 变化的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Interpreter-driven designs include rule interpreters that execute rules read from an external source, script or language interpreters that read and run programs, virtual machines, neural network engines that execute nets, constraint logic engines that read and reason with constraint sets, and so forth. This approach allows changing or parameterizing the behavior of a system via external logic expressions. The system is protected from the impact of logic variations by externalizing the logic, reading it in, and using an interpreter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              反射或元级设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这种方法的一个示例是使用 java.beans.Introspector 获取 BeanInfo 对象,请求 Bean 属性 X 的 getter Method 对象,然后调用 Method.invoke。通过使用内省和元语言服务的反射算法,该系统不受逻辑或外部代码变体的影响。它可能被视为数据驱动设计的特例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              An example of this approach is using the java.beans.Introspector to obtain a BeanInfo object, asking for the getter Method object for bean property X, and calling Method.invoke. The system is protected from the impact of logic or external code variations by reflective algorithms that use introspection and meta-language services. It may be considered a special case of data-driven designs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              统一访问

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              某些语言(如 Ada、Eiffel 和 C#)支持语法结构,以便方法和字段访问以相同的方式表示。例如,aCircle.radius 可以调用 radius():float 方法或直接引用 public 字段,具体取决于类的定义。我们可以从公共字段更改为访问方法,而无需更改客户端代码。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Some languages, such as Ada, Eiffel, and C#, support a syntactic construct so that both a method and field access are expressed the same way. For example, aCircle.radius may invoke a radius():float method or directly refer to a public field, depending on the definition of the class. We can change from public fields to access methods, without changing the client code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              标准语言

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              官方语言标准(如 SQL)可以防止各种语言的激增。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Official language standards such as SQL provide protection against a proliferation of varying languages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Liskov 替换原则 (LSP)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              LSP [Liskov88] 正式确定了防止接口的不同实现或超类的子类扩展的变化的原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              LSP [Liskov88] formalizes the principle of protection against variations in different implementations of an interface, or subclass extensions of a superclass.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              To quote:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这里需要的是类似于以下替换属性的内容:如果对于每个类型 S 的对象 o1,都有一个类型 T 的对象 o2,使得对于用 T 定义的所有程序 P,当 o1 替换为 o2 时,P 的行为保持不变,那么 S 是 T 的子类型 [Liskov88]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T [Liskov88].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              非正式地,引用类型 T(某些接口或抽象超类)的软件(方法、类等)应该可以正常工作,或者按预期与 T的任何替代实现或子类一起称为 S。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Informally, software (methods, classes, …) that refers to a type T (some interface or abstract superclass) should work properly or as expected with any substituted implementation or subclass of Tcall it S. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void addTaxes( ITaxCalculatorAdapter calculator, Sale sale )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 List taxLineItems = calculator.getTaxes( sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void addTaxes( ITaxCalculatorAdapter calculator, Sale sale )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 List taxLineItems = calculator.getTaxes( sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对于此方法 addTaxes,无论将 ITaxCalculatorAdapter 的哪种实现作为实际参数传入,该方法都应继续“按预期”工作。LSP 是一个简单的概念,对于大多数对象开发人员来说很直观,它将这种直觉正式化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For this method addTaxes, no matter what implementation of ITaxCalculatorAdapter is passed in as an actual parameter, the method should continue to work "as expected." LSP is a simple idea, intuitive to most object developers, that formalizes this intuition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              结构隐藏设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Structure-Hiding Designs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在本书的第一版中,一个重要的经典对象设计原则,称为 Don't Talk to Strangers or the Law of Demeter [Lieberherr88],被表述为九个 GRASP 模式之一。简而言之,这意味着避免创建遍历长对象结构路径并向远距离、间接(陌生)对象发送消息(或交谈)的设计。这样的设计对于对象结构的变化来说是脆弱的,这是不稳定的常见点。但在第二版中,更通用的 PV 取代了 Don't Talk to Strangers,因为后者是前者的特例。也就是说,实现对结构更改的保护的一种机制是应用 Don't Talk to Strangers 规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In the first edition of this book, an important, classic object design principle called Don't Talk to Strangers or the Law of Demeter [Lieberherr88] was expressed as one of the nine GRASP patterns. Briefly, it means to avoid creating designs that traverse long object structure paths and send messages (or talk) to distant, indirect (stranger) objects. Such designs are fragile with respect to changes in the object structuresa common point of instability. But in the second edition the more general PV replaced Don't Talk to Strangers, because the latter is a special case of the former. That is, a mechanism to achieve protection from structure changes is to apply the Don't Talk to Strangers rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Don't Talk to Strangers 对方法中应向哪些对象发送消息施加了约束。它指出,在方法中,消息只应发送到以下对象:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Don't Talk to Strangers places constraints on what objects you should send messages to within a method. It states that within a method, messages should only be sent to the following objects:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. this 对象(或 self)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. The this object (or self).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              3. 方法的参数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              4. A parameter of the method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              5. this 的一个属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              6. An attribute of this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7. 集合的一个元素,它是 this 的一个属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              8. An element of a collection which is an attribute of this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              9. 在方法中创建的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              10. An object created within the method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              目的是避免将客户端耦合到间接对象和对象之间的对象连接的知识。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The intent is to avoid coupling a client to knowledge of indirect objects and the object connections between objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              直接宾语是客户的 “familiars”,间接宾语是 “strangers”。客户应该与熟人交谈,避免与陌生人交谈。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Direct objects are a client's "familiars," indirect objects are "strangers." A client should talk to familiars, and avoid talking to strangers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这是一个(轻微地)违反 Don't Talk to Strangers 的例子。评论解释了违规行为。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Here is an example that (mildly) violates Don't Talk to Strangers. The comments explain the violation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private Sale sale;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void slightlyFragileMethod()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // sale.getPayment() sends a message to a "familiar" (passes #3)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // but in sale.getPayment().getTenderedAmount()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // the getTenderedAmount() message is to a "stranger" Payment
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 Money amount = sale.getPayment().getTenderedAmount();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private Sale sale;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void slightlyFragileMethod()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // sale.getPayment() sends a message to a "familiar" (passes #3)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // but in sale.getPayment().getTenderedAmount()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // the getTenderedAmount() message is to a "stranger" Payment
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 Money amount = sale.getPayment().getTenderedAmount();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              此代码遍历从熟悉的对象 (Sale) 到陌生对象 (Payment) 的结构连接,然后向其发送消息。它非常脆弱,因为它依赖于 Sale 对象连接到 Payment 对象的事实。实际上,这不太可能成为问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This code traverses structural connections from a familiar object (the Sale) to a stranger object (the Payment), and then sends it a message. It is very slightly fragile, as it depends on the fact that Sale objects are connected to Payment objects. Realistically, this is unlikely to be a problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              但是,请考虑下一个片段,它沿着结构路径遍历得更远:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              But, consider this next fragment, which traverses farther along the structural path:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void moreFragileMethod()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 AccountHolder holder =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.getPayment().getAccount().getAccountHolder();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void moreFragileMethod()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 AccountHolder holder =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    sale.getPayment().getAccount().getAccountHolder();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              或者更一般地说:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Or more generally:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 F someF =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    foo.getA().getB().getC().getD().getE().getF();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public void doX()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 F someF =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    foo.getA().getB().getC().getD().getE().getF();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 // …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这个例子是人为的,但你会看到这样的模式:沿着对象连接的路径走得更远,以便向远处的间接对象发送消息,与遥远的陌生人交谈。该设计与对象连接方式的特定结构耦合。程序在路径上遍历的距离越远,它就越脆弱。为什么?因为对象结构 (连接) 可能会更改。在年轻的应用程序或早期迭代中尤其如此。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The example is contrived, but you see the pattern: Traversing farther along a path of object connections in order to send a message to a distant, indirect objecttalking to a distant stranger. The design is coupled to a particular structure of how objects are connected. The farther along a path the program traverses, the more fragile it is. Why? Because the object structure (the connections) may change. This is especially true in young applications or early iterations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Karl Lieberherr 和他的同事在 Demeter 项目的保护伞下对良好的对象设计原则进行了研究。之所以确定这个 Demeter 定律(不要与陌生人交谈),是因为他们经常看到对象结构的变化和不稳定,因此与对象连接的知识相关的代码经常中断。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Karl Lieberherr and his colleagues have done research into good object design principles, under the umbrella of the Demeter project. This Law of Demeter (Don't Talk to Strangers) was identified because of the frequency with which they saw change and instability in object structure, and thus frequent breakage in code that was coupled to knowledge of object connections.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              然而,正如以下“投机性 PV 和选择你的战斗”部分所研究的那样,并不总是需要防止这种情况;这取决于 Object 结构的不稳定性。在标准库(比如 Java 库)中,对象类之间的结构连接相对稳定。在成熟的系统中,结构更稳定。在早期迭代的新系统中,它并不稳定。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Yet, as will be examined in the following "Speculative PV and Picking your Battles" section, it is not always necessary to protect against this; it depends on the instability of the object structure. In standard libraries (such as the Java libraries) the structural connections between classes of objects are relatively stable. In mature systems, the structure is more stable. In new systems in early iteration, it isn't stable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              一般来说,一个人在一条路上走得越远,它就越脆弱,因此遵守 Don't Talk to Strangers 更有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In general, the farther along a path one traverses, the more fragile it is, and thus it is more useful to conform to Don't Talk to Strangers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              严格遵守此法律防止结构变化需要向对象的 “familiars” 添加新的公共操作;这些操作提供最终所需的信息,并隐藏了获取信息的方式。例如,要支持前两种情况的 Don't Talk to Strangers:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Strictly obeying this lawprotection against structural variationsrequires adding new public operations to the "familiars" of an object; these operations provide the ultimately desired information, and hide how it was obtained. For example, to support Don't Talk to Strangers for the previous two cases:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // case 1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money amount = sale.getTenderedAmountOfPayment();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // case 2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              AccountHolder holder = sale.getAccountHolderOfPayment();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // case 1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Money amount = sale.getTenderedAmountOfPayment();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // case 2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              AccountHolder holder = sale.getAccountHolderOfPayment();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              禁忌

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Contraindications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注意:投机性 PV 和选择你的战斗

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Caution: Speculative PV and Picking Your Battles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              首先,有两点变化值得定义:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              First, two points of change are worth defining:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 变化点现有、当前系统或要求的变体,例如必须支持的多个税费计算器界面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • variation pointVariations in the existing, current system or requirements, such as the multiple tax calculator interfaces that must be supported.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 进化点将来可能出现但未出现在现有要求中的推测性变化点。[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [4] 在 UP 中,演变点可以在 Change Cases 中正式记录;每个都描述了演化点的相关方面,以造福于未来的架构师。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • evolution pointSpeculative points of variation that may arise in the future, but which are not present in the existing requirements.[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [4] In the UP, evolution points can be formally documented in Change Cases; each describes relevant aspects of an evolution point for the benefit of a future architect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV 适用于变异点和进化点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV is applied to both variation and evolution points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注意:有时,在进化点上投机性地“面向未来”的成本超过了简单、更“脆弱”的设计所产生的成本,该设计在必要时被重新设计以响应真正的变化压力。也就是说,在演化点进行工程保护的成本可能高于重新设计简单的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A caution: Sometimes the cost of speculative "future-proofing" at evolution points outweighs the cost incurred by a simple, more "brittle" design that is reworked as necessary in response to the true change pressures. That is, the cost of engineering protection at evolution points can be higher than reworking a simple design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,我记得一个寻呼机消息处理系统,其中架构师添加了脚本语言和解释器,以支持发展点的灵活性和受保护的变体。但是,在增量版本中的返工期间,复杂(且效率低下)的脚本被删除了,它根本不需要。当我开始 OO 编程时(在 1980 年代初期),我患上了“泛化 - 它就是”的疾病,我倾向于花费大量时间创建我真正需要编写的类的超类。我会让一切都变得非常通用和灵活(并防止变化),以应对未来真正会得到回报的情况,而这从未到来。我对何时值得付出努力的判断力很差。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, I recall a pager message-handling system where the architect added a scripting language and interpreter to support flexibility and protected variation at an evolution point. However, during rework in an incremental release, the complex (and inefficient) scripting was removedit simply wasn't needed. And when I started OO programming (in the early 1980s) I suffered the disease of "generalize-itis" in which I tended to spend many hours creating superclasses of the classes I really needed to write. I would make everything very general and flexible (and protected against variations), for that future situation when it would really pay offwhich never came. I was a poor judge of when it was worth the effort.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              重点不是提倡返工和脆弱的设计。如果对灵活性和保护免受变化的需求是现实的,那么应用 PV 就是有动力的。但是,如果是为了推测性的未来证明或可能性非常不确定的推测性“重用”,那么就需要克制和批判性思维。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The point is not to advocate rework and brittle designs. If the need for flexibility and protection from change is realistic, then applying PV is motivated. But if it is for speculative future-proofing or speculative "reuse" with very uncertain probabilities, then restraint and critical thinking is called for.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              新手开发人员倾向于脆弱的设计,中级开发人员倾向于过于花哨和灵活的通用设计(以从未使用过的方式)。专家设计师凭洞察力进行选择;也许是一个简单而脆弱的设计,其更改的成本与其可能性相平衡。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Novice developers tend toward brittle designs, intermediate developers tend toward overly fancy and flexible, generalized ones (in ways that never get used). Expert designers choose with insight; perhaps a simple and brittle design whose cost of change is balanced against its likelihood.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Benefits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 新变体所需的扩展很容易添加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Extensions required for new variations are easy to add.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 可以在不影响客户端的情况下引入新的实施。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • New implementations can be introduced without affecting clients.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 联轴器降低。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Coupling is lowered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 可以降低更改的影响或成本。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • The impact or cost of changes can be lowered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              相关模式和原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Related Patterns and Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 大多数设计原则和模式都是受保护变体的机制,包括多态性、接口、间接性、数据封装、大多数 GoF 设计模式等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Most design principles and patterns are mechanisms for protected variation, including polymorphism, interfaces, indirection, data encapsulation, most of the GoF design patterns, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 在 [Pree95] 中,变异和演化点称为“热点”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • In [Pree95] variation and evolution points are called "hot spots."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              也称为;似

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Also Known As; Similar To

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV 本质上与信息隐藏和开闭原则相同,这两个原则都是较旧的术语。作为模式社区中的“官方”模式,它于 1996 年被 Cockburn 在 [VCK96] 中命名为“Protected Variations”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PV is essentially the same as the information hiding and open-closed principles, which are older terms. As an "official" pattern in the pattern community, it was named "Protected Variations" in 1996 by Cockburn in [VCK96].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              信息隐藏

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Information Hiding

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              David Parnas 的著名论文 On the Criteria To Be Used in Decomposing Systems Into Modules [Parnas72] 是经常被引用但很少阅读的经典作品的一个例子。在其中,Parnas 介绍了信息隐藏的概念。也许是因为这个术语听起来像数据封装的概念,它被误解为数据封装,一些书籍错误地将这些概念定义为同义词。相反,Parnas 打算隐藏信息意味着在困难或可能发生变化的时候,向其他模块隐藏有关设计的信息。引用他对信息隐藏作为指导设计原则的讨论:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              David Parnas's famous paper On the Criteria To Be Used in Decomposing Systems Into Modules [Parnas72] is an example of classics often cited but seldom read. In it, Parnas introduces the concept of information hiding. Perhaps because the term sounds like the idea of data encapsulation, it has been misinterpreted as data encapsulation, and some books erroneously define the concepts as synonyms. Rather, Parnas intended information hiding to mean hide information about the design from other modules, at the points of difficulty or likely change. To quote his discussion of information hiding as a guiding design principle:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              相反,我们建议从一系列困难的设计决策或可能改变的设计决策开始。然后,每个模块都设计为对其他模块隐藏这样的决定。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              也就是说,Parnas 的信息隐藏与 PV 中表达的原理相同,而不仅仅是数据封装,这只是隐藏有关设计信息的众多技术之一。但是,该术语已被广泛地重新解释为数据封装的同义词,以至于不再可能在不产生误解的情况下按其原始含义使用它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              That is, Parnas's information hiding is the same principle expressed in PV, and not simply data encapsulationwhich is but one of many techniques to hide information about the design. However, the term has been so widely reinterpreted as a synonym for data encapsulation that it is no longer possible to use it in its original sense without misunderstanding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              开闭原理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Open-Closed Principle

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Bertrand Meyer 在 [Meyer88] 中描述的开闭原理 (OCP) 本质上等同于 PV 模式和信息隐藏。OCP 的定义是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Open-Closed Principle (OCP), described by Bertrand Meyer in [Meyer88], is essentially equivalent to the PV pattern and to information hiding. A definition of OCP is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模块应该同时是开放的(用于扩展;适应性强)和封闭的(模块是封闭的,不能以影响客户端的方式进行修改)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Modules should be both open (for extension; adaptable) and closed (the module is closed to modification in ways that affect clients).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              OCP 和 PV 本质上是同一原理的两种表达方式,但侧重点不同:在变化点和演变点提供保护。在 OCP 中,“module” 包括所有离散的软件元素,包括方法、类、子系统、应用程序等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              OCP and PV are essentially two expressions of the same principle, with different emphasis: protection at variation and evolution points. In OCP, "module" includes all discrete software elements, including methods, classes, subsystems, applications, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在 OCP 的上下文中,短语“closed for to X”意味着如果 X 发生变化,客户端不会受到影响。例如,“该类在实例字段定义方面是封闭的”,通过使用私有字段和公共访问方法的数据封装机制。同时,他们愿意修改私有数据的定义,因为外部客户端并不直接与私有数据耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In the context of OCP, the phrase "closed with respect to X" means that clients are not affected if X changes. For example, "the class is closed with respect to instance field definitions" through the mechanism of data encapsulation with private fields and public accessing methods. At the same time, they are open to modifying the definitions of the private data, because outside clients are not directly coupled to the private data.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              再举一个例子,通过实现稳定的 ITaxCalculatorAdapter 接口,“税收计算器适配器相对于其公共接口是关闭的”。但是,适配器可以通过私下修改以响应外部税收计算器的 API 的变化来扩展,而不会破坏其客户端。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As another example, "the tax calculator adapters are closed with respect to their public interface" through implementing the stable ITaxCalculatorAdapter interface. However, the adapters are open to extension by being privately modified in response to changes in the APIs of the external tax calculators, in ways that do not break their clients.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                第 26 章.应用 GoF 设计模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Chapter 26. Applying GoF Design Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                关注点的转移(到 Patterns)将对我们编写程序的方式产生深远而持久的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                沃德·坎宁安 (Ward Cunningham) 和拉尔夫·约翰逊 (Ralph Johnson)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The shift of focus (to patterns) will have a profound and enduring effect on the way we write programs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Ward Cunningham and Ralph Johnson

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 介绍并应用一些 GoF 设计模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Introduce and apply some GoF design patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 将 GRASP 原则显示为其他设计模式的泛化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Show GRASP principles as a generalization of other design patterns.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  本章探讨了 NextGen 案例研究的用例实现的 OO 设计,为接口可能有所不同的外部第三方服务、更复杂的产品定价规则和可插拔业务规则提供支持。重点是展示如何应用 Gang-of-Four (GoF) 和更基本的 GRASP 模式。它说明了对象设计和职责分配可以根据模式的应用来解释和学习,模式是可以组合到设计对象中的原则和习语词汇。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This chapter explores OO design for use-case realizations for the NextGen case study, providing support for external third-party services whose interfaces may vary, more complex product pricing rules, and pluggable business rules. The emphasis is to show how to apply the Gang-of-Four (GoF) and the more basic GRASP patterns. It illustrates that object design and the assignment of responsibilities can be explained and learned based on the application of patternsa vocabulary of principles and idioms that can be combined to design objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这里介绍了 23 种 GoF 设计模式中的一些,但更多模式也将在后面的章节中介绍,包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Some of the 23 GoF design patterns are introduced here, but more are also covered in later chapters, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  四人组设计模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Gang-of-Four Design Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GoF 设计模式及其开创性影响于 第 280 页首次引入。作为简要回顾,这些首先在 Design Patterns [GHJV95] 中进行了描述,这是一本开创性且非常受欢迎的著作,它提出了 23 种在对象设计中有用的模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GoF design patterns, and their seminal influence, were first introduced on p. 280. As a brief review, these were first described in Design Patterns [GHJV95], a seminal and extremely popular work that presents 23 patterns useful during object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  并非所有 23 种模式都得到广泛使用;也许 15 个是常见且最有用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Not all of the 23 patterns are widely used; perhaps 15 are common and most useful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  建议深入研究 Design Patterns 这本书,以便成为一名对象设计师,尽管该书假设读者已经是具有丰富经验的 OO 设计师,并且具有 C++ 和 Smalltalk 的背景。相比之下,这本书提供了一个介绍。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A thorough study of the Design Patterns book is recommended to grow as an object designer, although that book assumes the reader is already an OO designer with significant experienceand has a background in C++ and Smalltalk. In contrast, this book offers an introduction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    26.1. 适配器 (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    26.1. Adapter (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    414 页探讨的 NextGen 问题激发了多态性模式,其解决方案更具体地说是 GoF Adapter 模式的一个例子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The NextGen problem explored on p. 414 to motivate the Polymorphism pattern and its solution is more specifically an example of the GoF Adapter pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    适配器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Adapter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如何解决接口不兼容的问题,或者为不同接口的相似组件提供稳定的接口?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How to resolve incompatible interfaces, or provide a stable interface to similar components with different interfaces?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    通过中间适配器对象将组件的原始接口转换为另一个接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Convert the original interface of a component into another interface, through an intermediate adapter object.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    回顾:NextGen POS 系统需要支持多种外部第三方服务,包括税收计算器、信用授权服务、库存系统和会计系统等。每个 API 都有不同的 API,无法更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To review: The NextGen POS system needs to support several kinds of external third-party services, including tax calculators, credit authorization services, inventory systems, and accounting systems, among others. Each has a different API, which can't be changed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    一种解决方案是使用对象添加间接级别,这些对象使不同的外部接口适应应用程序中使用的一致接口。该解决方案如图 26.1 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A solution is to add a level of indirection with objects that adapt the varying external interfaces to a consistent interface used within the application. The solution is illustrated in Figure 26.1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 26.1.Adapter 模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如图 26.2 所示,将为所选的外部服务[1]实例化一个特定的适配器实例,例如用于会计的 SAP,并将 postSale 请求适应外部接口,例如通过 HTTPS 的 SOAP XML 接口用于 SAP 提供的 Intranet Web 服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As illustrated in Figure 26.2, a particular adapter instance will be instantiated for the chosen external service[1] , such as SAP for accounting, and will adapt the postSale request to the external interface, such as a SOAP XML interface over HTTPS for an intranet Web service offered by SAP.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] 在 J2EE 连接器体系结构中,这些外部服务的适配器更具体地称为资源适配器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] In the J2EE Connector Architecture, these adapters to external services are more specifically called resource adapters.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 26.2.使用适配器。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    指南:在类型名称中包含 pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline: Include Pattern in Type Name

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,类型名称包括模式名称 “Adapter”。这是一种相对常见的样式,其优点是可以轻松地与阅读代码或图表的其他人交流正在使用的设计模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Notice that the type names include the pattern name "Adapter." This is a relatively common style and has the advantage of easily communicating to others reading the code or diagrams what design patterns are being used.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    隐藏外部系统的资源适配器也可以被视为 Facade 对象(本章讨论的另一个 GoF 模式),因为它用单个对象(这是 Facade 的本质)包装对子系统或系统的访问。但是,当 wrapping 对象提供对不同外部接口的适应时,尤其存在将其称为资源适配器的动机。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A resource adapter that hides an external system may also be considered a Facade object (another GoF pattern discussed in this chapter), as it wraps access to the subsystem or system with a single object (which is the essence of Facade). However, the motivation to call it a resource adapter especially exists when the wrapping object provides adaptation to varying external interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      26.2. 一些 GRASP 原则作为其他模式的推广

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      26.2. Some GRASP Principles as a Generalization of Other Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以前对 Adapter 模式的使用可以看作是某些 GRASP 构建块的专用化:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The previous use of the Adapter pattern can be viewed as a specialization of some GRASP building blocks:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      适配器通过使用应用接口和多态性的 In间接 对象,支持在更改外部接口或第三方包方面受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Adapter supports Protected Variations with respect to changing external interfaces or third-party packages through the use of an Indirection object that applies interfaces and Polymorphism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      怎么了?模式过载!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What's the Problem? Pattern Overload!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern Almanac 2000 [Rising00] 列出了大约 500 种设计模式。从那时起,又出版了数百篇文章。好奇的开发人员没有时间根据此阅读清单实际编程!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Pattern Almanac 2000 [Rising00] lists around 500 design patterns. And many hundreds more have been published since then. The curious developer has no time to actually program given this reading list!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:了解基本原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A Solution: See the Underlying Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      是的,对于经验丰富的设计师来说,详细了解并记住 50+ 个最重要的设计模式是很重要的,但我们中很少有人能够学习或记住 1,000 个模式,甚至开始将这些模式过多地组织成一个有用的分类法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Yes, it's important for an experienced designer to know in detail and by memory 50+ of the most important design patterns, but few of us can learn or remember 1,000 patterns, or even start to organize that pattern plethora into a useful taxonomy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      但也有个好消息:大多数设计模式可以看作是一些基本 GRASP 原则的专业化。虽然研究详细的设计模式以加速学习确实很有帮助,但看到它们的基本主题(Protected Variations、Polymorphism、Indirection等)更有帮助,这有助于我们切入无数的细节,看到正在应用的设计技术的基本 “字母表”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      But there's good news: Most design patterns can be seen as specializations of a few basic GRASP principles. Although it is indeed helpful to study detailed design patterns to accelerate learning, it is even more helpful to see their underlying basic themes (Protected Variations, Polymorphism, Indirection, …) to help us to cut through the myriad details and see the essential "alphabet" of design techniques being applied.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      示例:Adapter 和 GRASP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Example: Adapter and GRASP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.1 说明了我的观点,即详细的设计模式可以根据 GRASP 原则的基本底层 “字母表” 来分析。UML 泛化关系用于建议概念连接。在这一点上,也许这个想法似乎是学术性的或过于分析性的。但确实如此,当你花几年时间应用和思考无数的设计模式时,你会越来越觉得底层主题是重要的,而 Adapter 或 Strategy 或其他任何东西的细节将变得次要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 26.1 illustrates my point that detailed design patterns can be analyzed in terms of the basic underlying "alphabet" of GRASP principles. UML generalization relationships are used to suggest the conceptual connections. At this point perhaps this idea seems academic or overly analytical. But it is truly the case that as you spend some years applying and reflecting on myriad design patterns, you will increasingly come to feel that it's the underlying themes that are important, and the fine details of Adapter or Strategy or whatever will become secondary.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.3.将 Adapter 与一些核心 GRASP 原则相关联。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        26.3. 设计过程中的“分析”发现:域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        26.3. "Analysis" Discoveries During Design: Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        请注意,在图 26.1 的 Adapter 设计中,getTaxes 操作返回 TaxLineItems 列表。也就是说,在对税收的处理方式和税收计算器的工作原理进行更深入的思考和调查后,建模者(我)意识到税收行项目列表与销售相关联,例如州税、联邦税等(政府总是有可能发明新的税收!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Observe that in the Adapter design in Figure 26.1, the getTaxes operation returns a list of TaxLineItems. That is, on deeper reflection and investigation of how taxes are handled and tax calculators work, the modeler (me) realized that a list of tax line items are associated with a sale, such as state tax, federal tax, and so forth (there is always the chance governments will invent new taxes!).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        除了是 Design Model 中新创建的软件类之外,它还是一个域概念。在设计或编程迭代开发过程中发现值得注意的领域概念是正常且常见的,并且对需求的精细理解支持这种增量发现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In addition to being a newly created software class in the Design Model, this is a domain concept. It is normal and common to discover noteworthy domain concepts and refined understanding of the requirements during design or programmingiterative development supports this kind of incremental discovery.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这个发现应该反映在 Domain Model(或 Glossary)中吗?如果域模型将来将用作以后设计工作的灵感来源,或者作为传达关键域概念的视觉学习辅助工具,那么添加它可能具有价值。图 26.4 说明了更新的 Domain Model。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Should this discovery be reflected in the Domain Model (or Glossary)? If the Domain Model will be used in the future as a source of inspiration for later design work, or as a visual learning aid to communicate the key domain concepts, then adding it could have value. Figure 26.4 illustrates an updated Domain Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 26.4.更新了部分域模型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          26.4. 工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          26.4. Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这也称为 Simple FactoryConcrete Factory。此模式不是 GoF 设计模式,而是非常普遍。它也是 GoF Abstract Factory 模式(第 597 页)的简化版,通常被描述为 Abstract Factory 的变体,尽管这并不严格准确。然而,由于它的普遍性和与 GoF 的关联,它现在被提出来。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This is also called Simple Factory or Concrete Factory. This pattern is not a GoF design pattern, but extremely widespread. It is also a simplification of the GoF Abstract Factory pattern (p. 597), and often described as a variation of Abstract Factory, although that's not strictly accurate. Nevertheless, because of its prevalence and association with GoF, it is presented now.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          适配器在设计中提出了一个新问题:在具有不同接口的外部服务的先前 Adapter 模式解决方案中,谁创建了适配器?如何确定要创建的适配器类,例如 TaxMaster-Adapter 或 GoodAsGoldTaxProAdapter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The adapter raises a new problem in the design: In the prior Adapter pattern solution for external services with varying interfaces, who creates the adapters? And how to determine which class of adapter to create, such as TaxMaster-Adapter or GoodAsGoldTaxProAdapter?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果某个域对象创建了它们,那么域对象的职责将超越纯粹的应用程序逻辑(例如销售总额计算),并涉及与外部软件组件的连接相关的其他问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If some domain object creates them, the responsibilities of the domain object are going beyond pure application logic (such as sales total calculations) and into other concerns related to connectivity with external software components.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这一点强调了另一个基本设计原则(通常被认为是架构设计原则):设计以保持关注点的分离。也就是说,将不同的关注点模块化或分离到不同的领域,以便每个关注点都有一个有凝聚力的目标。从根本上说,它是 GRASP 高内聚原则的应用。例如,软件对象的域层强调相对纯粹的 application logic 责任,而另一组对象负责关注与外部系统的连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This point underscores another fundamental design principle (usually considered an architectural design principle): Design to maintain a separation of concerns. That is, modularize or separate distinct concerns into different areas, so that each has a cohesive purpose. Fundamentally, it is an application of the GRASP High Cohesion principle. For example, the domain layer of software objects emphasizes relatively pure application logic responsibilities, whereas a different group of objects is responsible for the concern of connectivity to external systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因此,选择域对象(例如 Register)来创建适配器并不支持关注点分离的目标,并且会降低其内聚性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Therefore, choosing a domain object (such as a Register) to create the adapters does not support the goal of a separation of concerns, and lowers its cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在这种情况下,一种常见的替代方法是应用 Factory 模式,其中定义一个 Pure Fabrication“工厂”对象来创建对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A common alternative in this case is to apply the Factory pattern, in which a Pure Fabrication "factory" object is defined to create objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factory 对象具有以下几个优点:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factory objects have several advantages:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 将复杂创建的责任分离到内聚的帮助程序对象中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Separate the responsibility of complex creation into cohesive helper objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 隐藏可能复杂的创建逻辑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Hide potentially complex creation logic.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 允许引入增强性能的内存管理策略,例如对象缓存或回收。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Allow introduction of performance-enhancing memory management strategies, such as object caching or recycling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当存在特殊考虑时,例如复杂的创建逻辑、希望分离创建责任以获得更好的凝聚力等,谁应该负责创建对象?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who should be responsible for creating objects when there are special considerations, such as complex creation logic, a desire to separate the creation responsibilities for better cohesion, and so forth?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          创建一个名为 Factory 的 Pure Fabrication 对象,用于处理创建。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Create a Pure Fabrication object called a Factory that handles the creation.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factory 解决方案如图 26.5 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A Factory solution is illustrated in Figure 26.5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 26.5.Factory 模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,在 ServicesFactory 中,决定创建哪个类的逻辑是通过从外部源读取类名(例如,如果使用 Java,则通过系统属性),然后动态加载类来解析的。这是部分数据驱动设计的示例。此 design 根据适配器的 implementation class 的更改实现 Protected Changes。在不更改此工厂类中的源代码的情况下,我们可以通过更改属性值并确保新类在 Java 类路径中可见以供加载来创建新适配器类的实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that in the ServicesFactory, the logic to decide which class to create is resolved by reading in the class name from an external source (for example, via a system property if Java is used) and then dynamically loading the class. This is an example of a partial data-driven design. This design achieves Protected Variations with respect to changes in the implementation class of the adapter. Without changing the source code in this factory class, we can create instances of new adapter classes by changing the property value and ensuring that the new class is visible in the Java class path for loading.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          工厂通常使用 Singleton 模式进行访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factories are often accessed with the Singleton pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            26.5. 单例 (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            26.5. Singleton (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ServicesFactory 在设计中提出了另一个新问题:谁创建了工厂本身,以及如何访问它?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The ServicesFactory raises another new problem in the design: Who creates the factory itself, and how is it accessed?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            首先,请注意,该进程中只需要一个 factory 实例。其次,快速思考表明,可能需要从代码中的不同位置调用此工厂的方法,因为不同位置需要访问适配器以调用外部服务。因此,存在一个可见性问题:如何获得这个单个 ServicesFactory 实例的可见性?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            First, observe that only one instance of the factory is needed within the process. Second, quick reflection suggests that the methods of this factory may need to be called from various places in the code, as different places need access to the adapters for calling on the external services. Thus, there is a visibility problem: How to get visibility to this single ServicesFactory instance?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            一种解决方案是将 ServicesFactory 实例作为参数传递到发现可见性需求的任何位置,或者使用永久引用初始化需要可见性的对象。这是可能的,但不方便;另一种方法是 Singleton 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            One solution is pass the ServicesFactory instance around as a parameter to wherever a visibility need is discovered for it, or to initialize the objects that need visibility to it, with a permanent reference. This is possible but inconvenient; an alternative is the Singleton pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            有时,需要支持全局可见性或对类的单个实例的单个访问点,而不是其他形式的可见性。对于 ServicesFactory 实例来说,情况就是如此。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Occasionally, it is desirable to support global visibility or a single access point to a single instance of a class rather than some other form of visibility. This is true for the ServicesFactory instance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            单身 人士

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Singleton

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            只允许一个类的一个实例它是 “singleton”。对象需要一个全局的单一访问点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Exactly one instance of a class is allowedit is a "singleton." Objects need a global and single point of access.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            定义返回单例的类的静态方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Define a static method of the class that returns the singleton.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,图 26.6 显示了 Singleton 模式的实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, Figure 26.6 shows an implementation of the Singleton pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 26.6.ServicesFactory 类中的单例模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            应用 UML:请注意 singleton 的图示方式,名称隔间的右上角有一个 '1'。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Applying UML: Notice how a singleton is illustrated, with a '1' in the top right corner of the name compartment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            因此,关键思想是类 X 定义了一个静态方法 getInstance,该方法本身提供 X 的单个实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Thus, the key idea is that class X defines a static method getInstance that itself provides a single instance of X.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用这种方法,开发人员可以通过类的静态 getInstance 方法对这个单个实例进行全局可见性,如下例所示:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            With this approach, a developer has global visibility to this single instance, via the static getInstance method of the class, as in this example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void initialize()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               … do some work …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // accessing the singleton Factory via the getInstance call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               accountingAdapter =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ServicesFactory.getInstance().getAccountingAdapter();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               … do some work …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // other methods…
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public void initialize()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               … do some work …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               // accessing the singleton Factory via the getInstance call
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               accountingAdapter =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ServicesFactory.getInstance().getAccountingAdapter();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               … do some work …
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // other methods…
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            由于对公共类的可见性在范围上是全局的(在大多数语言中),因此在代码中的任何位置,在任何类的任何方法中,都可以编写

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Since visibility to public classes is global in scope (in most languages), at any point in the code, in any method of any class, one can write

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SingletonClass.getInstance()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SingletonClass.getInstance()

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ,以便获得对 singleton 实例的可见性,然后向其发送一条消息,例如 SingletonClass.getInstance().doFoo()。而且,能够在全球范围内 doFoo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            in order to obtain visibility to the singleton instance, and then send it a message, such as SingletonClass.getInstance().doFoo(). And it's hard to beat the feeling of being able to globally doFoo!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            实现和设计问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Implementation and Design Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            经常调用单例 getInstance 方法。在多线程应用程序中,惰性初始化逻辑的创建步骤是需要线程并发控制的关键部分。因此,假设实例是延迟初始化的,则通常使用并发控制包装该方法。例如,在 Java 中:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A Singleton getInstance method is often frequently called. In multi-threaded applications, the creation step of the lazy initialization logic is a critical section requiring thread concurrency control. Thus, assuming the instance is lazy initialized, it is common to wrap the method with concurrency control. In Java, for example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public static synchronized ServicesFactory getInstance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               if ( instance == null )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // critical section if multithreaded application
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  instance = new ServicesFactory();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               return instance;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public static synchronized ServicesFactory getInstance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               if ( instance == null )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // critical section if multithreaded application
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  instance = new ServicesFactory();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               return instance;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            关于惰性初始化的主题,为什么不更喜欢预先初始化,就像这个例子一样呢?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            On the subject of lazy initialization, why not prefer eager initialization, as in this example?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public class ServicesFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // eager initialization
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private static ServicesFactory instance =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               new ServicesFactory();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public static ServicesFactory getInstance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               return instance;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // other methods...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public class ServicesFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // eager initialization
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            private static ServicesFactory instance =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               new ServicesFactory();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            public static ServicesFactory getInstance()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               return instance;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            // other methods...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            通常首选第一种延迟初始化方法,至少出于以下原因:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The first approach of lazy initialization is usually preferred for at least these reasons:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 如果实例从未实际访问过,则可以避免创建工作(并且可能保留“昂贵”的资源)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Creation work (and perhaps holding on to "expensive" resources) is avoided, if the instance is never actually accessed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • getInstance 延迟初始化有时包含复杂的条件创建逻辑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • The getInstance lazy initialization sometimes contains complex and conditional creation logic.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 26.7.由于 '1' 标记,在 UML 中指示隐式 getInstance 单例模式消息。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            另一个常见的 Singleton 实现问题是:为什么不将类本身的所有服务方法设为静态方法,而不是将实例对象与实例端方法一起使用呢?例如,如果我们向 ServicesFactory 添加一个名为 getAccountingAdapter静态方法,该怎么办。但是,由于以下原因,实例和实例端方法通常是首选:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Another common Singleton implementation question is: Why not make all the service methods static methods of the class itself, instead of using an instance object with instance-side methods? For example, what if we add a static method called getAccountingAdapter to ServicesFactory. But, an instance and instance-side methods are usually preferred for these reasons:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 实例端方法允许将单例类子类化和细化为子类;static 方法不是多态的(虚拟的),并且不允许在大多数语言的子类中覆盖(不包括 Smalltalk)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Instance-side methods permit subclassing and refinement of the singleton class into subclasses; static methods are not polymorphic (virtual) and don't permit overriding in subclasses in most languages (Smalltalk excluded).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 大多数面向对象的远程通信机制(例如,Java 的 RMI)仅支持远程启用实例方法,而不支持静态方法。singleton 实例可以远程启用,尽管这很少发生。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Most object-oriented remote communication mechanisms (for example, Java's RMI) only support remote-enabling of instance methods, not static methods. A singleton instance could be remote-enabled, although that is admittedly rarely done.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 在所有应用程序上下文中,类并不总是单例。在应用程序 X 中,它可能是一个单例,但在应用程序 Y 中可能是“多吨”。在设计开始时认为对象将是单例,然后发现需要在同一进程中有多个实例的情况也并不少见。因此,实例端解决方案提供了灵活性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • A class is not always a singleton in all application contexts. In application X, it may be a singleton, but it may be a "multi-ton" in application Y. It is also not uncommon to start off a design thinking the object will be a singleton, and then discovering a need for multiple instances in the same process. Thus, the instance-side solution offers flexibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Singleton 模式通常用于 Factory 对象和 Facade 对象,这是将要讨论的另一种 GoF 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Singleton pattern is often used for Factory objects and Facade objectsanother GoF pattern that will be discussed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              26.6. 具有不同接口的外部服务问题的结论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              26.6. Conclusion of the External Services with Varying Interfaces Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Adapter、Factory 和 Singleton 模式的组合已用于从外部税收计算器、会计系统等的不同接口提供受保护的变体。图 26.8 说明了在 use-case 实现中使用这些的更大上下文。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A combination of Adapter, Factory, and Singleton patterns have been used to provide Protected Variations from the varying interfaces of external tax calculators, accounting systems, and so forth. Figure 26.8 illustrates a larger context of using these in the use-case realization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 26.8.应用于设计的 Adapter、Factory 和 Singleton 模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这种设计可能并不理想,而且总是有改进的余地。但是,本案例研究中努力实现的目标之一是说明至少可以从一组原则或模式 “构建块” 构建设计中构建,并且有一种有条不紊的方法来执行和解释设计。我真诚地希望,可以看到图 26.8 中的设计是如何从基于 Controller、Creator、Protected Variations、Low Coupling、High Cohesion、Indirection、Polymorphism、Adapter、Factory 和 Singleton 的推理中产生的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This design may not be ideal, and there is always room for improvement. But one of the goals strived for in this case study is to illustrate that at least a design can be constructed from a set of principles or pattern "building blocks," and that there is a methodical approach to doing and explaining a design. It is my sincere hope that it is possible to see how the design in Figure 26.8 arose from reasoning based on Controller, Creator, Protected Variations, Low Coupling, High Cohesion, Indirection, Polymorphism, Adapter, Factory, and Singleton.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              请注意,当对模式有共同的理解时,设计人员在对话或文档中可以多么简洁。我可以说,“为了处理外部服务的不同接口问题,让我们使用从 Singleton Factory 生成的 Adapters。对象设计师确实有听起来像这样的对话;使用模式和模式名称有助于提高设计交流中的抽象级别。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Note how succinct a designer can be in conversation or documentation when there is a shared understanding of patterns. I can say, "To handle the problem of varying interfaces for external services, let's use Adapters generated from a Singleton Factory." Object designers really do have conversations that sound like this; using patterns and pattern names supports raising the level of abstraction in design communication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                26.7. 策略 (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                26.7. Strategy (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                下一个要解决的设计问题是提供更复杂的定价逻辑,例如当天的商店范围折扣、老年人折扣等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The next design problem to be resolved is to provide more complex pricing logic, such as a store-wide discount for the day, senior citizen discounts, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                销售的定价策略(也称为规则、政策或算法)可能会有所不同。在一个时期内,所有销售额可能会享受 10% 的折扣,如果销售总额超过 10 美元,则可能会享受 200 美元的折扣,以及无数其他变化。我们如何为这些不同的定价算法进行设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The pricing strategy (which may also be called a rule, policy, or algorithm) for a sale can vary. During one period it may be 10% off all sales, later it may be $10 off if the sale total is greater than $200, and myriad other variations. How do we design for these varying pricing algorithms?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                策略

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Strategy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                如何针对不同但相关的算法或策略进行设计?如何设计更改这些算法或策略的能力?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How to design for varying, but related, algorithms or policies? How to design for the ability to change these algorithms or policies?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在单独的类中定义每个算法/策略/策略,并使用通用接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Define each algorithm/policy/strategy in a separate class, with a common interface.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                由于定价行为因策略(或算法)而异,因此我们创建多个 SalePricingStrategy 类,每个类都有一个多态 getTotal 方法(参见图 26.9)。每个 getTotal 方法都将 Sale 对象作为参数,以便定价策略对象可以从 Sale 中找到折扣前的价格,然后应用折扣规则。每个 getTotal 方法的实现将有所不同:PercentDiscountPricingStrategy 将按百分比折扣,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Since the behavior of pricing varies by the strategy (or algorithm), we create multiple SalePricingStrategy classes, each with a polymorphic getTotal method (see Figure 26.9). Each getTotal method takes the Sale object as a parameter, so that the pricing strategy object can find the pre-discount price from the Sale, and then apply the discounting rule. The implementation of each getTotal method will be different: PercentDiscountPricingStrategy will discount by a percentage, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 26.9.定价策略类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                策略对象附加到上下文对象,即它应用算法的对象。在此示例中,上下文对象是 Sale。当 getTotal 消息发送到 Sale 时,它会将一些工作委托给其 strategy 对象,如图 26.10 所示。发送到 context 对象和 strategy 对象的消息不需要具有相同的名称,如本例中所示(例如,getTotalgetTotal),但这是通用的。然而,通常确实需要上下文对象将对自身的引用 (this) 传递给策略对象,以便策略对上下文对象具有参数可见性,以便进一步协作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A strategy object is attached to a context objectthe object to which it applies the algorithm. In this example, the context object is a Sale. When a getTotal message is sent to a Sale, it delegates some of the work to its strategy object, as illustrated in Figure 26.10. It is not required that the message to the context object and the strategy object have the same name, as in this example (for example, getTotal and getTotal), but it is common. However, it is commonindeed, usually requiredthat the context object pass a reference to itself (this) on to the strategy object, so that the strategy has parameter visibility to the context object, for further collaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 26.10.合作战略。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,上下文对象 (Sale) 需要其策略的属性 visibility。这反映在图 26.11 的 DCD 中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Observe that the context object (Sale) needs attribute visibility to its strategy. This is reflected in the DCD in Figure 26.11.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 26.11.Context 对象需要其策略的属性可见性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                使用 Factory 创建策略

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Creating a Strategy with a Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                有不同的定价算法或策略,它们会随着时间的推移而变化。谁应该制定策略?一种简单的方法是再次应用 Factory 模式:PricingStrategyFactory可以负责创建应用程序所需的所有策略(所有可插拔或更改的算法或策略)。与 ServicesFactory 一样,它可以从系统属性(或某些外部数据源)中读取定价策略的实现类的名称,然后创建它的实例。通过这种部分数据驱动设计(或反射设计),可以在 NextGen POS 应用程序运行定价策略时随时动态更改,方法是指定要创建的不同策略类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There are different pricing algorithms or strategies, and they change over time. Who should create the strategy? A straightforward approach is to apply the Factory pattern again: A PricingStrategyFactory can be responsible for creating all strategies (all the pluggable or changing algorithms or policies) needed by the application. As with the ServicesFactory, it can read the name of the implementation class of the pricing strategy from a system property (or some external data source), and then make an instance of it. With this partial data-driven design (or reflective design) one can dynamically change at any timewhile the NextGen POS application is runningthe pricing policy, by specifying a different class of Strategy to create.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,策略使用了新工厂;也就是说,与 ServicesFactory 不同。这支持 High Cohesion 的目标每个工厂都紧密地专注于创建相关的对象系列。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Observe that a new factory was used for the strategies; that is, different than the ServicesFactory. This supports the goal of High Cohesioneach factory is cohesively focused on creating a related family of objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UML请注意,在图 26.11 中,通过有向关联引用的是接口 ISalePricingStrategy,而不是具体类。这表示 Sale 中的 reference 属性将根据接口而不是类进行声明,以便接口的任何实现都可以绑定到该属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UML Observe that in Figure 26.11 the reference via a directed association is to the interface ISalePricingStrategy, not to a concrete class. This indicates that the reference attribute in the Sale will be declared in terms of the interface, not a class, so that any implementation of the interface can be bound to the attribute.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,由于定价策略经常变化(可能是每小时一次),因此不希望将创建的策略实例缓存在PricingStrategyFactory的字段中,而是通过读取其类名的外部属性,然后实例化策略,每次重新创建一个。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Note that because of the frequently changing pricing policy (it could be every hour), it is not desirable to cache the created strategy instance in a field of the PricingStrategyFactory, but rather to re-create one each time, by reading the external property for its class name, and then instantiating the strategy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                与大多数工厂一样,PricingStrategyFactory将是一个单例(一个实例)并通过单例模式访问(参见图 26.12)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                And as with most factories, the PricingStrategyFactory will be a singleton (one instance) and accessed via the Singleton pattern (see Figure 26.12).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 26.12.战略工厂。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                当创建一个 Sale 实例时,它可以向工厂询问其定价策略,如图 26.13 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When a Sale instance is created, it can ask the factory for its pricing strategy, as shown in Figure 26.13.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 26.13.创建策略。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                读取和初始化百分比值

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                最后,一个直到现在一直被忽视的设计问题是如何找到百分比或绝对折扣的不同数字的问题。例如,在星期一,PercentageDiscountPricingStrategy 的百分比值可能为 10%,但在星期二为 20%。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Finally, a design problem that has been ignored until now is the issue of how to find the different numbers for the percentage or absolute discounts. For example, on Monday, the PercentageDiscountPricingStrategy may have a percentage value of 10%, but 20% on Tuesday.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                另请注意,百分比折扣可能与买家类型(例如老年人)相关,而不是与时间段相关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Note also that a percentage discount may be related to the type of buyer, such as a senior citizen, rather than to a time period.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这些数字将存储在一些外部数据存储中,例如关系数据库,因此可以轻松更改它们。那么,什么对象会读取它们并确保它们被分配给策略呢?一个合理的选择是 StrategyFactory 本身,因为它正在创建定价策略,并且可以知道要从数据存储中读取的百分比(“当前商店折扣”、“高级折扣”等)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                These numbers will be stored in some external data store, such as a relational database, so they can be easily changed. So, what object will read them and ensure they are assigned to the strategy? A reasonable choice is the StrategyFactory itself, since it is creating the pricing strategy, and can know which percentage to read from a data store ("current store discount," "senior discount," and so forth).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                从外部数据存储中读取这些数字的设计从简单到复杂不等,例如普通的 JDBC SQL 调用(如果是 Java 技术,例如)或与添加间接级别的对象协作,以隐藏特定位置、数据查询语言或数据存储类型。分析与数据存储相关的变异和演变点将揭示是否需要受保护的变异。例如,我们可以问:“我们是否都愿意长期致力于使用理解 SQL 的关系数据库?如果是这样,从 StrategyFactory 中进行简单的 JDBC 调用就足够了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Designs to read these numbers from external data stores vary from the simple to the complex, such as a plain JDBC SQL call (if Java technologies, as an example) or collaborating with objects that add levels of indirection in order to hide the particular location, data query language, or type of data store. Analyzing the variation and evolution points with respect to the data store will reveal if there is a need for protected variation. For example, we could ask, "Are we all comfortable with a long-term commitment to using a relational database that understands SQL?". If so, a simple JDBC call from within the StrategyFactory may suffice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在动态变化的定价策略方面,受保护的变体是通过 Strategy 和 Factory 模式实现的。策略建立在多态性和接口之上,允许在对象设计中使用可插拔算法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Protected Variations with respect to dynamically changing pricing policies has been achieved with the Strategy and Factory patterns. Strategy builds on Polymorphism and interfaces to allow pluggable algorithms in an object design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                策略基于多态性,并针对不断变化的算法提供受保护的变体。策略通常由 Factory 创建。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Strategy is based on Polymorphism, and provides Protected Variations with respect to changing algorithms. Strategies are often created by a Factory.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  26.8. 复合 (GoF) 和其他设计原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  26.8. Composite (GoF) and Other Design Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  提出另一个有趣的需求和设计问题:我们如何处理多个相互冲突的定价策略的情况?例如,假设商店在今天(星期一)有以下生效策略:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To raise yet another interesting requirements and design problem: How do we handle the case of multiple, conflicting pricing policies? For example, suppose a store has the following policies in effect today (Monday):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 20% 老年人折扣政策

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 20% senior discount policy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 优惠顾客折扣,销售额满 15 美元可享受 400% 的折扣

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • preferred customer discount of 15% off sales over $400

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 周一,满 50 美元立减 500 美元

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • on Monday, there is $50 off purchases over $500

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 购买 1 箱大吉岭茶,所有商品可享受 15% 的折扣

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • buy 1 case of Darjeeling tea, get 15% discount off of everything

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  假设一位老年人也是首选客户,他购买了 1 箱大吉岭茶和 600 美元的素食汉堡(显然是一位热爱印度奶茶的热情素食者)。应采用什么定价策略?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Suppose a senior who is also a preferred customer buys 1 case of Darjeeling tea, and $600 of veggieburgers (clearly an enthusiastic vegetarian who loves chai). What pricing policy should be applied?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  澄清一下:现在有一些定价策略与销售相关,这些策略主要由三个因素决定:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To clarify: There are now pricing strategies that attach to the sale by virtue of three factors:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 时间段 (Monday)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. time period (Monday)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 客户类型 (高级)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. customer type (senior)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 特定订单项产品(大吉岭茶)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. a particular line item product (Darjeeling tea)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  另一点需要澄清的是:四个示例策略中的三个实际上只是“百分比折扣”策略,这简化了我们对问题的看法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Another point of clarification: Three of the four example policies are really just "percentage discount" strategies, which simplifies our view of the problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这个问题的部分答案需要定义 store 的冲突解决策略。通常,商店会应用“最适合客户”(最低价格)冲突解决策略,但这不是必需的,并且可能会发生变化。例如,在财务困难时期,商店可能不得不使用“最高价格”冲突解决策略。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Part of the answer to this problem requires defining the store's conflict resolution strategy. Usually, a store applies the "best for the customer" (lowest price) conflict resolution strategy, but this is not required, and it could change. For example, during a difficult financial period, the store may have to use a "highest price" conflict resolution strategy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  首先要注意的是,可以存在多种共存的策略,即一次销售可能有多种定价策略。需要注意的另一点是,定价策略可以与客户类型(例如,老年人)相关。这具有创建设计含义:在为客户创建定价策略时,StrategyFactory 必须知道 customer 类型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The first point to note is that there can exist multiple co-existing strategies, that is, one sale may have several pricing strategies. Another point to note is that a pricing strategy can be related to the type of customer (for example, a senior). This has creation design implications: The customer type must be known by the StrategyFactory at the time of creation of a pricing strategy for the customer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  同样,定价策略可以与所购买的商品类型(例如,大吉岭茶)相关联。这同样具有创建设计含义:在创建受产品影响的定价策略时,StrategyFactory 必须知道 ProductDescription

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Similarly, a pricing strategy can be related to the type of product being bought (for example, Darjeeling tea). This likewise has creation design implications: The ProductDescription must be known by the StrategyFactory at the time of creation of a pricing strategy influenced by the product.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  有没有办法更改设计,以便 Sale 对象不知道它是在处理一种还是多种定价策略,并且还提供用于解决冲突的设计?是的,使用 Composite 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Is there a way to change the design so that the Sale object does not know if it is dealing with one or many pricing strategies, and also offer a design for the conflict resolution? Yes, with the Composite pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  复合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Composite

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如何以与非复合(原子)对象相同的方式(多态)处理对象的组或组合结构?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  How to treat a group or composition structure of objects the same way (polymorphically) as a non-composite (atomic) object?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  为复合对象和原子对象定义类,以便它们实现相同的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Define classes for composite and atomic objects so that they implement the same interface.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  例如,一个名为 CompositeBestForCustomerPricingStrategy 的新类(嗯,至少它是描述性的)可以实现 ISalesPricingStrategy,并且它本身包含其他 ISalesPricingStrategy 对象。图 26.14 详细解释了设计思路。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For example, a new class called CompositeBestForCustomerPricingStrategy (well, at least it's descriptive) can implement the ISalesPricingStrategy and itself contain other ISalesPricingStrategy objects. Figure 26.14 explains the design idea in detail.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.14.复合模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,在此设计中,复合类(如 CompositeBestForCustomerPricingStrategy)继承了一个属性 pricingStrategies,该属性包含更多 ISalePricingStrategy 对象的列表。这是复合对象的一个特征:外部复合对象包含内部对象的列表,外部对象和内部对象都实现相同的接口。也就是说,复合类本身实现 ISalePricingStrategy 接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Observe that in this design, the composite classes such as CompositeBestForCustomerPricingStrategy inherit an attribute pricingStrategies that contains a list of more ISalePricingStrategy objects. This is a signature feature of a composite object: The outer composite object contains a list of inner objects, and both the outer and inner objects implement the same interface. That is, the composite class itself implements the ISalePricingStrategy interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  因此,我们可以将复合 CompositeBestForCustomerPricingStrategy 对象(其中包含其他策略)或原子 PercentDiscountPricingStrategy 对象附加到 Sale 对象,而 Sale 不知道也不关心其定价策略是原子策略还是复合策略,它对 Sale 对象来说看起来是一样的。它只是另一个实现ISalePricingStrategy接口并理解getTotal消息的对象(图 26.15)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Thus, we can attach either a composite CompositeBestForCustomerPricingStrategy object (which contains other strategies inside of it) or an atomic PercentDiscountPricingStrategy object to the Sale object, and the Sale does not know or care if its pricing strategy is an atomic or composite strategyit looks the same to the Sale object. It is just another object that implements the ISalePricingStrategy interface and understands the getTotal message (Figure 26.15).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.15.与复合材料协作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML图 26.15 中,请注意一种指示实现接口的对象的方法,而我们并不关心指定确切的实现类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML In Figure 26.15, please note a way to indicate objects that implement an interface, when we don't care to specify the exact implementation class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  为了用 Java 中的一些示例代码来阐明,CompositePricingStrategy 及其子类之一定义如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To clarify with some sample code in Java, the CompositePricingStrategy and one of its subclasses are defined as follows:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // superclass so all subclasses can inherit a List of strategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public abstract class CompositePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     implements ISalePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  protected List strategies = new ArrayList();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public add( ISalePricingStrategy s )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     strategies.add( s );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public abstract Money getTotal( Sale sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // a Composite Strategy that returns the lowest total
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // of its inner SalePricingStrategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class CompositeBestForCustomerPricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     extends CompositePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public Money getTotal( Sale sale )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Money lowestTotal = new Money( Integer.MAX_VALUE );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // iterate over all the inner strategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for( Iterator i = strategies.iterator(); i.hasNext(); )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ISalePricingStrategy strategy =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           (ISalePricingStrategy)i.next();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Money total = strategy.getTotal( sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        lowestTotal = total.min( lowestTotal );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  return lowestTotal;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // superclass so all subclasses can inherit a List of strategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public abstract class CompositePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     implements ISalePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  protected List strategies = new ArrayList();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public add( ISalePricingStrategy s )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     strategies.add( s );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public abstract Money getTotal( Sale sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // a Composite Strategy that returns the lowest total
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  // of its inner SalePricingStrategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public class CompositeBestForCustomerPricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     extends CompositePricingStrategy
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  public Money getTotal( Sale sale )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Money lowestTotal = new Money( Integer.MAX_VALUE );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     // iterate over all the inner strategies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     for( Iterator i = strategies.iterator(); i.hasNext(); )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ISalePricingStrategy strategy =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           (ISalePricingStrategy)i.next();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Money total = strategy.getTotal( sale );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        lowestTotal = total.min( lowestTotal );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  return lowestTotal;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.16.UML 中的抽象超类、抽象方法和继承。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  创建多个 SalePricingStrategies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Creating Multiple SalePricingStrategies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  使用 Composite 模式,我们使一组多个(且冲突的)定价策略在 Sale 对象上看起来就像一个定价策略一样。包含该组的复合对象还实现 ISalePricingStrategy 接口。这个设计问题更具挑战性(也更有趣)的部分是:我们何时创建这些策略?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  With the Composite pattern, we have made a group of multiple (and conflicting) pricing strategies look to the Sale object like a single pricing strategy. The composite object that contains the group also implements the ISalePricingStrategy interface. The more challenging (and interesting) part of this design problem is: When do we create these strategies?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  理想的设计首先创建一个 Composite,其中包含当前时刻的商店折扣策略(如果没有活动,则可以设置为 0% discount),例如一些 PercentageDiscountPricingStrategy。然后,如果在方案的后续步骤中,发现另一种定价策略也适用(如高级折扣),则使用继承的 CompositePricingStrategy.add 方法将其添加到组合中将很容易。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A desirable design will start by creating a Composite that contains the present moment's store discount policy (which could be set to 0% discount if none is active), such as some PercentageDiscountPricingStrategy. Then, if at a later step in the scenario, another pricing strategy is discovered to also apply (such as senior discount), it will be easy to add it to the composite, using the inherited CompositePricingStrategy.add method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在方案中,有三个点可以将定价策略添加到组合中:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  There are three points in the scenario where pricing strategies may be added to the composite:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 当前商城定义的折扣,在创建促销时添加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Current store-defined discount, added when the sale is created.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 客户类型折扣,在将客户类型传达到 POS 时添加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Customer type discount, added when the customer type is communicated to the POS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 产品类型折扣(如果购买了大吉岭茶,则为总销售额提供 15% 的折扣),在产品进入销售时添加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. Product type discount (if bought Darjeeling tea, 15% off the overall sale), added when the product is entered to the sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第一种情况的设计如图 26.17 所示。与前面讨论的原始设计一样,要实例化的策略类名称可以作为系统属性读取,并且可以从外部数据存储中读取百分比值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The design of the first case is shown in Figure 26.17. As in the original design discussed earlier, the strategy class name to instantiate could be read as a system property, and a percentage value could be read from an external data store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.17.创建复合策略。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  对于客户类型折扣的第二种情况,请首先回顾之前识别此要求的用例扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For the second case of a customer type discount, first recall the use case extension which previously recognized this requirement:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  用例 UC1:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  扩展 (或替代流):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extensions (or Alternative Flows):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5b.买家表示他们有资格享受折扣(例如,员工、优先顾客)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 收银员发出 discount 请求信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. 收银员 输入 Customer identification。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 系统根据折扣规则显示折扣总额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5b. Customer says they are eligible for a discount (e.g., employee, preferred customer)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. Cashier signals discount request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Cashier enters Customer identification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. System presents discount total, based on discount rules.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这表示除了 makeNewSale、enterItem、endSalemakePayment 之外,POS 系统上还有一个新的系统操作。我们将这第五个系统操作称为 enterCustomerForDiscount;它可以选择在 endSale 操作之后发生。这意味着必须通过用户界面 customerID 进行某种形式的客户标识。也许它可以从读卡器或通过键盘捕获。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This indicates a new system operation on the POS system, in addition to makeNewSale, enterItem, endSale, and makePayment. We will call this fifth system operation enterCustomerForDiscount; it may optionally occur after the endSale operation. It implies that some form of customer identification will have to come in through the user interface, the customerID. Perhaps it can be captured from a card reader, or via the keyboard.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第二种情况的设计如图 26.18图 26.19 所示。毫不奇怪,工厂对象负责创建附加定价策略。它可能会生成另一个 PercentageDiscountPricingStrategy,例如,表示高级折扣。但与原始创建设计一样,类的选择将作为系统属性读入,客户类型的特定百分比也将作为系统属性读入,以提供与更改类或值相关的受保护变体。请注意,由于 Composite 模式,Sale 可能附加了两个或三个相互冲突的定价策略,但它对于 Sale 对象来说仍然看起来像一个策略。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The design of the second case is shown in Figure 26.18 and Figure 26.19. Not surprisingly, the factory object is responsible for the creation of the additional pricing strategy. It may make another PercentageDiscountPricingStrategy that represents, for example, a senior discount. But as with the original creation design, the choice of class will be read in as a system property, as will the specific percentage for the customer type, to provide Protected Variations with respect to changing the class or values. Note that by virtue of the Composite pattern, the Sale may have two or three conflicting pricing strategies attached to it, but it continues to look like a single strategy to the Sale object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.18.为客户折扣创建定价策略,第 1 部分.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 26.19.为客户折扣创建定价策略,第 2 部分.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML 图 26.18图 26.19 显示了交互图中的一个重要 UML 2 思想:使用 ref 和 sd 框架来关联图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML Figure 26.18 and Figure 26.19 show an important UML 2 idea in interaction diagrams: Using the ref and sd frame to relate diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在设计中考虑 GRASP 和其他原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  从一些基本的 GRASP 模式的角度回顾一下思考:对于第二种情况,为什么不让 RegisterPricingStrategyFactory 发送消息,以创建这个新的定价策略,然后将其传递给 Sale?原因之一是支持 Low Coupling。Sale 已经与工厂耦合;通过使 Register 也与它协作,设计中的耦合将增加。此外,Sale 是了解其当前定价策略(即将修改)的信息专家;因此,根据 Expert,委托 Sale 也是合理的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To review thinking in terms of some basic GRASP patterns: For this second case, why not have the Register send a message to the PricingStrategyFactory, to create this new pricing strategy and then pass it to the Sale? One reason is to support Low Coupling. The Sale is already coupled to the factory; by making the Register also collaborate with it, the coupling in the design would increase. Furthermore, the Sale is the Information Expert that knows its current pricing strategy (which is going to be modified); so by Expert, it is also justified to delegate to the Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在设计中观察 customerID 通过 Register 转换为 Customer 对象,请求 Store 提供 Customer,给定一个 ID。首先,将 getCustomer 责任交给 Store 是合理的;通过信息专家和低代表性差距的目标,商店可以了解所有客户。并且 Register 询问 Store,因为 Register 已经具有对 Store 的属性可见性(来自早期的设计工作);如果 Sale 必须向 Store 请求,则 Sale 将需要对 Store 的引用,从而将耦合提高到超出其当前水平,因此不支持低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Observe in the design that customerID is transformed into a Customer object via the Register asking the Store for a Customer, given an ID. First, it is justifiable to give the getCustomer responsibility to the Store; by Information Expert and the goal of low representational gap, the Store can know all the Customers. And the Register asks the Store, because the Register already has attribute visibility to the Store (from earlier design work); if the Sale had to ask the Store, the Sale would need a reference to the Store, increasing the coupling beyond its current levels, and therefore not supporting Low Coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  对象的 ID

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  IDs to Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  其次,为什么要将 customerID(“ID”可能是一个数字)转换为 Customer 对象?这是对象设计中的常见做法,用于将事物的键和 ID 转换为真正的对象。此转换通常在 ID 或密钥从 UI 层进入设计模型的域层后不久发生。它没有模式名称,但它可能是模式的候选者,因为它是经验丰富的对象设计师的常见习语,也许是 Object 的 ID。何苦?拥有一个真正的 Customer 对象,它封装了一组关于客户的信息,并且可以具有行为(例如,与 Information Expert 相关),随着设计的增长,它通常会变得有益和灵活,即使设计人员最初并不认为需要真正的对象,而是认为一个普通的数字或 ID 就足够了。请注意,在早期设计中,将 itemID 转换为 ProductDescription 对象是此 ID 到 Objects 模式的另一个示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Second, why transform the customerID (an "ID"perhaps a number) into a Customer object? This is a common practice in object designto transform keys and IDs for things into true objects. This transformation often takes place shortly after an ID or key enters the domain layer of the Design Model from the UI layer. It doesn't have a pattern name, but it could be a candidate for a pattern because it is such a common idiom among experienced object designersperhaps IDs to Objects. Why bother? Having a true Customer object that encapsulates a set of information about the customer, and which can have behavior (related to Information Expert, for example), frequently becomes beneficial and flexible as the design grows, even if the designer does not originally perceive a need for a true object and thought instead that a plain number or ID would be sufficient. Note that in the earlier design, the transformation of the itemID into a ProductDescription object is another example of this IDs to Objects pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将聚合对象作为参数传递

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Pass Aggregate Object as Parameter

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  最后,请注意,在 addCustomerPricingStrategy(s:Sale) 消息中,我们将 Sale 传递给工厂,然后工厂转身向 Sale 请求 CustomerPricingStrategy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Finally, note that in the addCustomerPricingStrategy(s:Sale) message we pass a Sale to the factory, and then the factory turns around and asks for the Customer and PricingStrategy from the Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  为什么不直接从 Sale 中提取这两个对象,而是将 CustomerPricingStrategy 传递给工厂呢?答案是另一个常见的对象设计习惯用法:避免从父对象或聚合对象中提取子对象,然后传递子对象。相反,传递包含子对象的聚合对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Why not just extract these two objects from the Sale, and instead pass in the Customer and PricingStrategy to the factory? The answer is another common object design idiom: Avoid extracting child objects out of parent or aggregate objects, and then passing around the child objects. Rather, pass around the aggregate object that contains child objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  遵循这个原则增加了灵活性,因为这样工厂就可以以我们以前可能没有预料到的方式与整个销售合作(这很常见),并且作为推论,它减少了预测工厂对象需求的需求;设计师只是将整个 Sale 作为参数传递,而不知道工厂可能需要哪些更具体的对象。虽然这个成语没有名字,但它与 Low Coupling 和 Protected Variations 有关。也许它可以称为 Pass Aggregate Object as Parameter 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Following this principle increases flexibility, because then the factory can collaborate with the entire Sale in ways we may not have previously anticipated as necessary (which is very common), and as a corollary, it reduces the need to anticipate what the factory object needs; the designer just passes as a parameter the entire Sale, without knowing what more particular objects the factory may need. Although this idiom does not have a name, it is related to Low Coupling and Protected Variations. Perhaps it could be called the Pass Aggregate Object as Parameter pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这个设计问题在对象设计中被压缩为许多技巧。熟练的对象设计者通过研究其已发布的解释,将其中许多模式牢记在心,并内化了核心原则,例如 GRASP 系列中描述的原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This design problem was squeezed for many tips in object design. A skilled object designer has many of these patterns committed to memory through studying their published explanations, and has internalized core principles, such as those described in the GRASP family.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,尽管 Composite 的此应用程序应用于 Strategy 系列,但 Composite 模式可以应用于其他类型的对象,而不仅仅是策略。例如,通常通过使用 Composite 创建包含其他命令的 “macro commands” 命令。命令模式将在后续章节中介绍。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Please note that although this application of Composite was to a Strategy family, the Composite pattern can be applied to other kinds of objects, not just strategies. For example, it is common to create "macro commands"commands that contain other commandsthrough the use of Composite. The Command pattern is described in a subsequent chapter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Composite 通常与 Strategy 和 Command 模式一起使用。Composite 基于多态性,并向客户端提供 Protected Variations,因此,如果其相关对象是 atomic 或 composite,则不会受到影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Composite is often used with the Strategy and Command patterns. Composite is based on Polymorphism and provides Protected Variations to a client so that it is not impacted if its related objects are atomic or composite.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    26.9. Facade (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    26.9. Facade (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    此迭代选择的另一个要求是可插拔的业务规则。也就是说,在场景中的可预测点,例如当 makeNewSaleenterItem 出现在 Process Sale 用例中时,或者当收银员开始兑现时,希望购买 NextGen POS 的不同客户希望稍微自定义其行为。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Another requirement chosen for this iteration is pluggable business rules. That is, at predictable points in the scenarios, such as when makeNewSale or enterItem occurs in the Process Sale use case, or when a cashier starts cashing in, different customers who wish to purchase the NextGen POS would like to customize its behavior slightly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    更准确地说,假设需要可以使操作无效的规则。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To be more precise, assume that rules are desired that can invalidate an action. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设在创建新的销售时,可以确定它将通过礼券支付(这是可能的并且很常见)。然后,商店可能有一个规则,即在使用礼品券时只允许购买一件商品。因此,在第一个操作之后的后续 enterItem 操作应无效。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Suppose when a new sale is created, it is possible to identify that it will be paid by a gift certificate (this is possible and common). Then, a store may have a rule to only allow one item to be purchased if a gift certificate is used. Consequently, subsequent enterItem operations, after the first, should be invalidated.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 如果销售是通过礼品券支付的,则使应退还给买家的所有付款类型的零钱无效,但另一张礼品券除外。例如,如果收银员要求以现金形式找零,或作为客户商店账户的信用额度,则这些请求无效。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • If the sale is paid by a gift certificate, invalidate all payment types of change due back to the customer except for another gift certificate. For example, if the cashier requested change in the form of cash, or as a credit to the customer's store account, invalidate those requests.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 假设在创建新的销售时,可以确定它是针对慈善捐赠的(从商店到慈善机构)。商店也可能有一条规则,只允许每个项目少于 250 美元,并且如果当前登录的“收银员”是经理,则只允许将项目添加到销售中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Suppose when a new sale is created, it is possible to identify that it is for a charitable donation (from the store to the charity). A store may also have a rule to only allow item entries less than $250 each, and also to only add items to the sale if the currently logged in "cashier" is a manager.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在需求分析方面,必须确定所有用例(enterItem、chooseCashChange 等)中的特定场景点。对于此探索,将仅考虑 enterItem 点,但相同的解决方案同样适用于所有点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In terms of requirements analysis, the specific scenario points across all use cases (enterItem, chooseCashChange, ...) must be identified. For this exploration, only the enterItem point will be considered, but the same solution applies equally to all points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    假设软件架构师需要一个对现有软件组件影响较小的设计。也就是说,她或他想要设计一个关注点分离,并将这个规则处理分解成一个单独的关注点。此外,假设架构师不确定此可插入规则处理的最佳实现,并且可能希望尝试不同的解决方案来表示、加载和评估规则。例如,可以使用 Strategy 模式实现规则,也可以使用免费的开源规则解释器来读取和解释一组 IF-THEN 规则,或者使用购买的商业规则解释器以及其他解决方案来实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Suppose that the software architect wants a design that has low impact on the existing software components. That is, she or he wants to design for a separation of concerns, and factor out this rule handling into a separate concern. Furthermore, suppose that the architect is unsure of the best implementation for this pluggable rule handling, and may want to experiment with different solutions for representing, loading, and evaluating the rules. For example, rules can be implemented with the Strategy pattern, or with free open-source rule interpreters that read and interpret a set of IF-THEN rules, or with commercial, purchased rule interpreters, among other solutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    为了解决这个设计问题,可以使用 Facade 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To solve this design problem, the Facade pattern can be used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    外观

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Facade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    需要一个通用的统一接口来连接一组不同的实现或接口,例如在一个子系统中。子系统中的许多事物可能存在不需要的耦合,或者子系统的实现可能会发生变化。该怎么办?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A common, unified interface to a disparate set of implementations or interfacessuch as within a subsystemis required. There may be undesirable coupling to many things in the subsystem, or the implementation of the subsystem may change. What to do?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    定义与 subsystem(子系统)的单一接触点包装子系统的 Faface 对象。此 Facade 对象提供单个统一接口,并负责与子系统组件协作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Define a single point of contact to the subsystema facade object that wraps the subsystem. This facade object presents a single unified interface and is responsible for collaborating with the subsystem components.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Facade 是一个 “前端” 对象,它是子系统服务的单一入口点[2] ;子系统的 implementation 和其他组件是私有的,外部组件无法看到。Facade 提供子系统实现中更改的受保护变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A Facade is a "front-end" object that is the single point of entry for the services of a subsystem[2] ; the implementation and other components of the subsystem are private and can't be seen by external components. Facade provides Protected Variations from changes in the implementation of a subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [2] “子系统”在这里以非正式的意义表示相关组件的单独分组,并不完全按照 UML 中的定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [2] "Subsystem" is here used in an informal sense to indicate a separate grouping of related components, not exactly as defined in the UML.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    例如,我们将定义一个 “rule engine” 子系统,其具体实现尚不清楚。[3] 它将负责针对操作评估一组规则(通过一些隐藏的实现),然后指示是否有任何规则使操作无效。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For example, we will define a "rule engine" subsystem, whose specific implementation is not yet known.[3] It will be responsible for evaluating a set of rules against an operation (by some hidden implementation), and then indicating if any of the rules invalidated the operation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [3] 有几个免费的开源和商业规则引擎。例如,Jess,一个免费的学术用途规则引擎,可在 http://herzberg.ca.sandia.gov/jess/.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [3] There are several free open source and commercial rule engines. For example, Jess, a free-for-academic-use rule engine available at http://herzberg.ca.sandia.gov/jess/.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    此子系统的 Fafront 对象将称为 POSRuleEngineFacade。参见图 26.20。设计者决定将对此门面的调用放在已定义为可插拔规则点的方法的开头附近,如下例所示:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The facade object to this subsystem will be called POSRuleEngineFacade. See Figure 26.20. The designer decides to place calls to this facade near the start of the methods that have been defined as the points for pluggable rules, as in this example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public void makeLineItem( ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       SalesLineItem sli = new SalesLineItem( desc, quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // call to the Facade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       if ( POSRuleEngineFacade.getInstance().isInvalid( sli, this ) )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          return;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       lineItems.add( sli );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public void makeLineItem( ProductDescription desc, int quantity )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       SalesLineItem sli = new SalesLineItem( desc, quantity );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // call to the Facade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       if ( POSRuleEngineFacade.getInstance().isInvalid( sli, this ) )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          return;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       lineItems.add( sli );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    } // end of class
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 26.20.带有 Facade 的 UML 封装图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意 Singleton 模式的使用。立面通常通过 Singleton 访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note the use of the Singleton pattern. Facades are often accessed via Singleton.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    通过这种设计,规则的表示和评估方式的复杂性和实现隐藏在“规则引擎”子系统中,可通过 POSRuleEngineFacade 门面访问。请注意,由 Faspect 对象隐藏的子系统可能包含数十或数百个对象类,甚至是非面向对象的解决方案,但作为子系统的客户端,我们只看到它的一个公共访问点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With this design, the complexity and implementation of how rules will be represented and evaluated are hidden in the "rules engine" subsystem, accessed via the POSRuleEngineFacade facade. Observe that the subsystem hidden by the facade object could contain dozens or hundreds of classes of objects, or even a non-object-oriented solution, yet as a client to the subsystem, we see only its one public access point.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    并且在某种程度上实现了关注点的分离,所有规则处理关注点都已委托给另一个子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    And a separation of concerns has been achieved to some degreeall the rule-handling concerns have been delegated to another subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Facade 模式简单且应用广泛。它将子系统隐藏在对象后面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The Facade pattern is simple and widely used. It hides a subsystem behind an object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    立面通常通过 Singleton 模式进行访问。它们通过添加 In间接 对象来帮助支持低耦合,从而从子系统的实现中提供受保护的变体。外部对象与子系统中的一个点耦合:立面对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Facades are usually accessed via the Singleton pattern. They provide Protected Variations from the implementation of a subsystem, by adding an Indirection object to help support Low Coupling. External objects are coupled to one point in a subsystem: the facade object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如 Adapter 模式中所述,适配器对象可用于包装对具有不同接口的外部系统的访问。这是一种 Facade,但重点是提供对不同接口的适应,因此它更具体地称为适配器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As described in the Adapter pattern, an adapter object may be used to wrap access to external systems with varying interfaces. This is a kind of facade, but the emphasis is to provide adaptation to varying interfaces, and thus it is more specifically called an adapter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      26.10. 观察者/发布-订阅/委托事件模型 (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      26.10. Observer/Publish-Subscribe/Delegation Event Model (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      迭代的另一个要求是添加 GUI 窗口的能力,以便在总销售额发生变化时刷新其销售总额的显示(参见图 26.21)。这个想法是解决这种情况,然后在以后的迭代中,将解决方案扩展到刷新其他更改数据的 GUI 显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Another requirement for the iteration is adding the ability for a GUI window to refresh its display of the sale total when the total changes (see Figure 26.21). The idea is to solve the problem for this one case, and then in later iterations, extend the solution to refreshing the GUI display for other changing data as well.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.21.当销售总额发生变化时更新界面。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为什么不执行以下操作作为解决方案呢?当 Sale 更改其总计时,Sale 对象会向窗口发送一条消息,要求它刷新其显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Why not do the following as a solution? When the Sale changes its total, the Sale object sends a message to a window, asking it to refresh its display.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      回顾一下,模型-视图分离原则不鼓励使用此类解决方案。它指出“模型”对象(非 UI 对象,如 Sale)不应了解视图或表示对象,如窗口。它将低耦合从其他层提升到对象的表示 (UI) 层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To review, the Model-View Separation principle discourages such solutions. It states that "model" objects (non-UI objects such as a Sale) should not know about view or presentation objects such as a window. It promotes Low Coupling from other layers to the presentation (UI) layer of objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      支持这种低耦合的结果是,它允许将视图或表示层替换为新层,或将特定窗口替换为新窗口,而不会影响非 UI 对象。如果模型对象不知道 Java Swing 对象(例如),则可以取消插入 Swing 接口,或者取消特定窗口,然后插入其他内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A consequence of supporting this low coupling is that it allows the replacement of the view or presentation layer by a new one, or of particular windows by new windows, without impacting the non-UI objects. If model objects do not know about Java Swing objects (for example), then it is possible to unplug a Swing interface, or unplug a particular window, and plug in something else.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因此,模型-视图分离支持与不断变化的用户界面相关的受保护变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thus, Model-View Separation supports Protected Variations with respect to a changing user interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为了解决这个设计问题,可以使用 Observer 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To solve this design problem, the Observer pattern can be used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      名字:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Name:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      观察者 (发布-订阅)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer (Publish-Subscribe)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      问题:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Problem:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      不同类型的订阅服务器对象对发布服务器对象的状态更改或事件感兴趣,并希望在发布服务器生成事件时以自己独特的方式做出反应。此外,发布者希望保持与订阅者的低耦合。该怎么办?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Different kinds of subscriber objects are interested in the state changes or events of a publisher object, and want to react in their own unique way when the publisher generates an event. Moreover, the publisher wants to maintain low coupling to the subscribers. What to do?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      解决方案:(建议)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution: (advice)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      定义 “subscriber” 或 “listener” 接口。订阅者实现此接口。发布者可以动态注册对事件感兴趣的订阅者,并在事件发生时通知他们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Define a "subscriber" or "listener" interface. Subscribers implement this interface. The publisher can dynamically register subscribers who are interested in an event and notify them when an event occurs.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.22 中详细描述了一个示例解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An example solution is described in detail in Figure 26.22.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.22.观察者模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      此示例中的主要思想和步骤:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The major ideas and steps in this example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. 定义了一个接口;在本例中,PropertyListener 与操作 onPropertyEvent 一起使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. An interface is defined; in this case, PropertyListener with the operation onPropertyEvent.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. 定义用于实现接口的窗口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • SaleFrame1 将实现方法 onPropertyEvent

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4. Define the window to implement the interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • SaleFrame1 will implement the method onPropertyEvent.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      5. 初始化 SaleFrame1 窗口时,将 Sale 实例传递给它,从中显示总计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      6. When the SaleFrame1 window is initialized, pass it the Sale instance from which it is displaying the total.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      7. SaleFrame1 窗口注册或订阅 Sale 实例,以便通过 addPropertyListener 消息通知“属性事件”。也就是说,当属性 (如 total) 更改时,窗口希望收到通知。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      8. The SaleFrame1 window registers or subscribes to the Sale instance for notification of "property events," via the addPropertyListener message. That is, when a property (such as total) changes, the window wants to be notified.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      9. 请注意,Sale 不知道 SaleFrame1 对象;相反,它只知道实现 PropertyListener 接口的对象。这降低了 Sale 与 window 的耦合,耦合仅与 interface 耦合,而不是 GUI 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      10. Note that the Sale does not know about SaleFrame1 objects; rather, it only knows about objects that implement the PropertyListener interface. This lowers the coupling of the Sale to the windowthe coupling is only to an interface, not to a GUI class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      11. 因此,Sale 实例是 “property events” 的发布者。当总数发生变化时,它会遍历所有订阅的 PropertyListener,并通知每个 PropertyListener。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      12. The Sale instance is thus a publisher of "property events." When the total changes, it iterates across all subscribing PropertyListeners, notifying each.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SaleFrame1 对象是观察者/订阅者/侦听器。在图 26.23 中,它订阅Sale 的 property events 的兴趣,Sale 是 property events 的发布者Sale 将对象添加到其 PropertyListener 订阅者列表中。请注意,Sale 不知道 SaleFrame1 作为 SaleFrame1 对象,而只知道 PropertyListener 对象;这降低了从模型到 View 层的耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The SaleFrame1 object is the observer/subscriber/listener. In Figure 26.23, it subscribes to interest in property events of the Sale, which is a publisher of property events. The Sale adds the object to its list of PropertyListener subscribers. Note that the Sale does not know about the SaleFrame1 as a SaleFrame1 object, but only as a PropertyListener object; this lowers the coupling from the model up to the view layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.23.观察者 SaleFrame1 订阅发布者 Sale



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如图 26.24 所示,当 Sale 总额发生变化时,它会遍历所有注册的订阅者,并通过向每个订阅者发送 onPropertyEvent 消息来“发布事件”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As illustrated in Figure 26.24, when the Sale total changes, it iterates across all its registered subscribers, and "publishes an event" by sending the onPropertyEvent message to each.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.24.Sale 向其所有订阅者发布 property 事件。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      应用 UML:请注意图 26.24 中在交互图中处理多态消息的方法。onPropertyEvent 消息是多态的;多态实现的具体情况将显示在其他图表中,如图 26.25 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Applying UML: Note the approach to handing polymorphic messages in an interaction diagram, in Figure 26.24. The onPropertyEvent message is polymorphic; the specific cases of polymorphic implementation will be shown in other diagrams, as in Figure 26.25.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.25.订阅者 SaleFrame1 接收已发布事件的通知。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SaleFrame1 实现 PropertyListener 接口,因此实现 onPropertyEvent 方法。当 SaleFrame1 收到消息时,它会向其 JTextField GUI 窗口小部件对象发送一条消息,以使用新的销售总额进行刷新。见图 26.25

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SaleFrame1, which implements the PropertyListener interface, thus implements an onPropertyEvent method. When the SaleFrame1 receives the message, it sends a message to its JTextField GUI widget object to refresh with the new sale total. See Figure 26.25.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在此模式中,从模型对象 (Sale) 到视图对象 (SaleFrame1) 仍然存在一些耦合。但它是独立于表示层的接口 PropertyListener 接口的松散耦合。并且该设计不需要任何订阅者对象实际注册到发布者(无需侦听任何对象)。也就是说,Sale 中已注册的 PropertyListeners 列表可以为空。总之,耦合到不需要存在且可以动态添加(或删除)对象的通用接口支持低耦合。因此,关于不断变化的用户界面的受保护变体是通过使用接口和多态性来实现的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In this pattern, there is still some coupling from the model object (the Sale) to the view object (the SaleFrame1). But it is a loose coupling to an interface independent of the presentation layerthe PropertyListener interface. And the design does not require any subscriber objects to actually be registered with the publisher (no objects have to be listening). That is, the list of registered PropertyListeners in the Sale can be empty. In summary, coupling to a generic interface of objects that do not need to be present, and which can be dynamically added (or removed), supports low coupling. Therefore, Protected Variations with respect to a changing user interface has been achieved through the use of an interface and polymorphism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为什么称为 Observer、Publish-Subscription 或 Delegation Event Model?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Why Is It Called Observer, Publish-Subscribe, or Delegation Event Model?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      最初,这个习语被称为 publish-subscribe,并且仍然以这个名字广为人知。一个对象“发布事件”,例如 Sale 在总数更改时发布“property event”。没有对象可能对此事件感兴趣,在这种情况下, Sale 没有注册订阅者。但是,感兴趣的对象通过要求发布通知它们来 “订阅” 或注册对事件感兴趣。这是通过 Sale.addPropertyListener 消息完成的。事件发生时,注册的订阅者会收到一条消息的通知。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Originally, this idiom was called publish-subscribe, and it is still widely known by that name. One object "publishes events," such as the Sale publishing the "property event" when the total changes. No object may be interested in this event, in which case, the Sale has no registered subscribers. But objects that are interested, "subscribe" or register to interest in an event by asking the publishing to notify them. This was done with the Sale.addPropertyListener message. When the event happens, the registered subscribers are notified by a message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      之所以称为 Observer,是因为侦听器或订阅者正在观察事件;这个词在 1980 年代初期在 Smalltalk 中流行起来。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It has been called Observer because the listener or subscriber is observing the event; that term was popularized in Smalltalk in the early 1980s.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      它也被称为委托事件模型(在 Java 中),因为发布者将事件的处理委托给“侦听器”(subscribers;参见图 26.26)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It has also been called the Delegation Event Model (in Java) because the publisher delegates handling of events to "listeners" (subscribers; see Figure 26.26).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.26.谁是观察者、侦听器、订阅者和发布者?



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer 不仅用于连接 UI 和模型对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer Is Not Only for Connecting UIs and Model Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      前面的示例说明了如何使用 Observer 将非 UI 对象连接到 UI 对象。但是,其他用途也很常见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The previous example illustrated connecting a non-UI object to a UI object with Observer. However, other uses are common.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      此模式最普遍的用途是 GUI 小部件事件处理,在 Java 技术(AWT 和 Swing)和 Microsoft 的 .NET 中。每个 Widget 都是 GUI 相关事件的发布者,其他对象可以订阅对这些事件的兴趣。例如,Swing JButton 在按下时会发布“action event”。另一个对象将向该按钮注册,以便在按下该按钮时,该对象将收到一条消息并可以执行一些操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The most prevalent use of this pattern is for GUI widget event handling, in both Java technologies (AWT and Swing) and in Microsoft's .NET. Each widget is a publisher of GUI-related events, and other objects can subscribe to interest in these. For example, a Swing JButton publishes an "action event" when it is pressed. Another object will register with the button so that when it is pressed, the object is sent a message and can take some action.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      作为另一个示例,图 26.27 说明了 AlarmClock,它是警报事件和各种订阅者的发布者。此示例具有说明性,因为它强调许多类可以实现 AlarmListener 接口,许多对象可以同时成为注册侦听器,并且所有对象都可以以自己独特的方式对“警报事件”做出反应。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As another example, Figure 26.27 illustrates an AlarmClock, which is a publisher of alarm events and various subscribers. This example is illustrative in that it emphasizes that many classes can implement the AlarmListener interface, many objects can simultaneously be registered listeners, and all can react to the "alarm event" in their own unique way.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 26.27.Observer 应用于具有不同订阅者的警报事件。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      一个发布服务器可以有多个事件订阅者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      One Publisher Can Have Many Subscribers for an Event

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如图 26.27 所示,一个 publisher 实例可以有从 0 到多个注册订阅者。例如,一个 AlarmClock 实例可能具有三个已注册的 AlarmWindows、四个 Beeper 和一个 ReliabilityWatchDog。当警报事件发生时,所有这八个 AlarmListener 都会通过 onAlarmEvent 收到通知。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As suggested in Figure 26.27, one publisher instance could have from zero to many registered subscribers. For example, one instance of an AlarmClock could have three registered AlarmWindows, four Beepers, and one ReliabilityWatchDog. When an alarm event happens, all eight of these AlarmListeners are notified via an onAlarmEvent.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      事件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 Observer 的 Java 和 C# .NET 实现中,“事件”通过常规消息(如 onPropertyEvent)进行传达。此外,在这两种情况下,事件都更正式地定义为一个类,并填充了适当的事件数据。然后,该事件将作为事件消息中的参数传递。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In both the Java and C# .NET implementations of Observer, an "event" is communicated via a regular message, such as onPropertyEvent. Moreover, in both cases, the event is more formally defined as a class, and filled with appropriate event data. The event is then passed as a parameter in the event message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class PropertyEvent extends Event
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object sourceOfEvent;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private String propertyName;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object oldValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object newValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private void publishPropertyEvent(
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            String name, Object old, Object new )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            PropertyEvent evt =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             new PropertyEvent( this, "sale.total", old, new);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            for each AlarmListener al in alarmListeners
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             al.onPropertyEvent( evt );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class PropertyEvent extends Event
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object sourceOfEvent;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private String propertyName;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object oldValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private Object newValue;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class Sale
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         private void publishPropertyEvent(
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            String name, Object old, Object new )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            PropertyEvent evt =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             new PropertyEvent( this, "sale.total", old, new);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            for each AlarmListener al in alarmListeners
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             al.onPropertyEvent( evt );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      爪哇岛

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当 JDK 1.0 于 1996 年 1 月发布时,它包含一个基于分别称为 ObservableObserver 的类和接口的弱发布-订阅实现。这基本上是从 1980 年代早期在 Smalltalk 中实现的发布-订阅方法复制而来的,没有改进。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When the JDK 1.0 was released in January 1996, it contained a weak publish-subscribe implementation based on a class and interface called Observable and Observer, respectively. This was essentially copied without improvement from an early 1980s approach to publish-subscribe implemented in Smalltalk.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因此,在 1996 年末,作为 JDK 1.1 工作的一部分,Observable-Observer 设计实际上被更健壮的 Java 委派事件模型 (DEM) 版本的发布-订阅所取代,尽管保留了原始设计以实现向后兼容性(但通常要避免)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Therefore, in late 1996, as part of the JDK 1.1 effort, the Observable-Observer design was effectively replaced by the more robust Java Delegation Event Model (DEM) version of publish-subscribe, although the original design was kept for backward-compatibility (but in general to be avoided).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      本章中描述的设计与 DEM 一致,但略微简化以强调核心思想。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The designs that have been described in this chapter are consistent with the DEM, but slightly simplified to emphasize the core ideas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer 提供了一种在通信方面松散耦合对象的方法。发布者仅通过接口了解订阅者,订阅者可以向发布者动态注册(或取消注册)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer provides a way to loosely couple objects in terms of communication. Publishers know about subscribers only through an interface, and subscribers can register (or de-register) dynamically with the publisher.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer 基于多态性,并提供受保护的变体,以防止发布商知道发布商生成事件时与之通信的特定对象类和对象数量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observer is based on Polymorphism, and provides Protected Variations in terms of protecting the publisher from knowing the specific class of object, and number of objects, that it communicates with when the publisher generates an event.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        26.11. 总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        26.11. Conclusion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        从这个论述中可以得出的主要教训是,在模式的支持下,可以设计对象并分配责任。这些提供了一组可解释的惯用语,通过这些惯用语可以构建设计良好的面向对象的系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The main lesson to draw from this exposition is that objects can be designed and responsibilities assigned with the support of patterns. These provide an explainable set of idioms by which well-designed object-oriented systems can be built.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          26.12. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          26.12. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Design Patterns by Gamma, Helm, Johnson, and Vlissides 是开创性的模式文本,也是所有对象设计人员的必备读物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Design Patterns by Gamma, Helm, Johnson, and Vlissides is the seminal patterns text, and essential reading for all object designers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          每年都会举办一次“程序模式语言”(PLOP) 会议,从该会议中出版了年度模式纲要,包括程序设计的模式语言系列,第 1 卷、第 2 卷等。推荐整个系列。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Each year there is a "Pattern Languages of Programs" (PLOP) conference, from which is published an annual compendium of patterns, in the series Pattern Languages of Program Design, volumes 1, 2, and so forth. The entire series is recommended.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          面向模式的软件体系结构,第 1 卷和第 2 卷,将模式的讨论进一步扩展到更大规模的体系结构关注点。第 1 卷提出了模式分类法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Pattern-Oriented Software Architecture, volumes 1 and 2, furthered the discussion of patterns to larger-scale architectural concerns. Volume 1 presented a taxonomy of patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有数百种已发布的模式。Rising 的 Pattern Almanac 总结了其中相当大一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          There are hundreds of published patterns. The Pattern Almanac by Rising summarizes a respectable percentage of them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            第 27 章.迭代 3中间主题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Chapter 27. Iteration 3Intermediate Topics

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 定义迭代 3 的要求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Define the requirements for iteration-3.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Inception 和 iteration-1 探索了许多基本的 OOA/D 建模基础知识。迭代 2 狭隘地强调对象设计。第三次迭代再次从更广泛的角度出发,探讨了各种分析和设计主题,包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Inception and iteration-1 explored many basic OOA/D modeling basics. Iteration-2 narrowly emphasized object design. This third iteration takes a broader view again, exploring a variety of analysis and design topics, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 更多的 GoF 设计模式,以及它们在框架设计中的应用,特别是持久化框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • more GoF design pattern, and their application to the design of frameworksin particular, a persistence framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 建筑分析;使用 N+1 视图模型记录架构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • architectural analysis; documenting architecture with the N+1 view model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 使用 UML 活动图进行流程建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • process modeling with UML activity diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 泛化和专业化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • generalization and specialization

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 包装设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • the design of packages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                27.1. 下一代 POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                27.1. NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                迭代 3 中的要求包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Requirements in iteration-3 include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 当无法访问远程服务时,提供到本地服务的故障转移。例如,如果无法访问远程 product 数据库,请使用包含缓存数据的本地版本。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Provide failover to local services when the remote services cannot be accessed. For example, if the remote product database can't be accessed, use a local version with cached data.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 为 POS 设备处理提供支持,例如现金抽屉和硬币分配器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Provide support for POS device handling, such as the cash drawer and coin dispenser.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 办理信用支付授权。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Handle credit payment authorization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 支持持久性对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Support for persistent objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  27.2. 垄断

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  27.2. Monopoly

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  迭代 3 中的要求包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Requirements in iteration-3 include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 同样,实现 Play Monopoly Game 用例的基本关键场景:玩家在棋盘的方格中移动。和以前一样,将游戏作为模拟运行,除了玩家数量之外,不需要用户输入。但是,在迭代 3 中,更多完整规则集适用。以下几点对这些进行了描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Again, implement a basic, key scenario of the Play Monopoly Game use case: players moving around the squares of the board. And as before, run the game as a simulation requiring no user input, other than the number of players. However, in iteration-3 more of the complete set of rules apply. These are described in the following points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 现在有 Lots、Railroads 和 Utility squares。当玩家降落在 Lot、Railroad 或 Utility 方格上时,以下逻辑适用......

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • There are now Lots, Railroads, and Utility squares. When a player lands on a Lot, Railroad or Utility square, the following logic applies…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 如果 Lot、Railroad 或 Utility 方格无人拥有,则登陆该方格的玩家可以购买该方格。如果他们购买了它,则 Lot、Railroad 或 Utility 方块的价格将从玩家的钱中扣除,玩家成为其所有者。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 价格是在游戏开始时设定的,但可能是任意的,例如,可以使用官方大富翁价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • If the Lot, Railroad or Utility square is not owned, the player who landed on the square may buy it. If they buy it, the price of the Lot, Railroad or Utility square is deducted from the player's money and the player becomes its owner.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • The price is set when the game starts, but is arbitraryfor example, the official Monopoly prices may be used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 如果 Lot、Railroad 或 Utility 方块归登陆其上的玩家所有,则不会发生任何事情。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • If the Lot, Railroad or Utility square is owned by the player that landed on it, nothing happens.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 如果 Lot、Railroad 或 Utility 方格的所有者不是登陆方格的玩家,则登陆方格的玩家必须向其所有者支付租金。租金计算如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 地块租金为 ( 指数 位置 ) 美元;例如,如果位置为 5,则为 5 美元。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 铁路租金是所有者拥有的铁路数量的 25 美元;例如,如果拥有 3 条铁路,则为 75 美元。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 水电费租金是玩家落在方格上时骰子上显示的数字的 4 倍(不要再次掷骰子)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • If the Lot, Railroad or Utility square is owner by a player other than the player that landed on it, the player that landed on the square must pay its owner rent. The rent calculations are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Lot rent is ( index position ) dollars; e.g., if position 5, then $5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Railroad rent is 25 dollars times the number of Railroads owned by the owner; e.g., if own 3 Railroads, then $75.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Utilities rent is 4 times the number shown on the dice when the player lands on the square (do not roll again)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    第 28 章.UML 活动图和建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Chapter 28. UML Activity Diagrams and Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果它没有备份,那么它就不重要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sysadmin 座右铭

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If it wasn't backed-up, then it wasn't important.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The Sysadmin Motto

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 介绍 UML 活动图表示法、示例和各种建模应用程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Introduce UML activity diagram notation, with examples, and various modeling applications.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UML 活动图显示流程中的顺序和并行活动。它们可用于对业务流程、工作流、数据流和复杂算法进行建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A UML activity diagram shows sequential and parallel activities in a process. They are useful for modeling business processes, workflows, data flows, and complex algorithms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        28.1. 示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        28.1. Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        基本的 UML 活动图表示法如图 28.1 所示,说明了 action、partition、fork、joinobject 节点。实质上,此图显示了一系列操作,其中一些操作可能是并行的。大多数符号都是不言自明的;两个微妙的点:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Basic UML activity diagram notation is shown in Figure 28.1, illustrating an action, partition, fork, join, and object node. In essence, this diagram shows a sequence of actions, some of which may be parallel. Most of the notation is self-explanatory; two subtle points:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 操作完成后,将出现一个自动传出过渡

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • once an action is finished, there is an automatic outgoing transition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 该图可以同时显示控制流和数据流

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • the diagram can show both control flow and data flow

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 28.1.基本的 UML 活动图表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          28.2. 如何应用活动图?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          28.2. How to Apply Activity Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          UML 活动图提供了丰富的表示法来显示一系列活动,包括并行活动。它可以应用于任何角度或目的,但对于可视化业务工作流程和流程以及使用案例来说很受欢迎。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A UML activity diagram offers rich notation to show a sequence of activities, including parallel activities. It may be applied to any perspective or purpose, but is popular for visualizing business workflows and processes, and use cases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          业务流程建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Business Process Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          我的一个客户从事快递包裹运输业务。运送包裹的过程非常不简单;涉及多方(客户、司机等)和许多步骤。尽管此过程可以用文本(在用例文本中)来捕获,但在这种情况下,活动图是图片胜过千言万语的一个很好的例子。我的客户使用活动图通过可视化来了解他们当前的复杂业务流程。分区可用于查看运输过程中涉及的多个参与方和并行操作,而对象节点则说明了正在移动的内容。在对当前流程进行建模后,他们直观地探索更改和优化。有关将 UML 活动图应用于业务流程建模的简单示例,请参见图 28.1。为了展示我的运输客户的流程模型,将填满一整面墙!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          One of my clients is in the express parcel shipping business. The process of shipping a parcel is very non-trivial; there are many parties involved (customer, driver, …) and many steps. Although this process can be captured in text (in use case text), in this case activity diagrams are a great example of pictures being worth a thousand words. My client uses activity diagrams to understand their current complex business processes by visualizing them. The partitions are useful to see the multiple parties and parallel actions involved in the shipping process, and the object nodes illustrate what's moving around. After modeling their current process they visually explore changes and optimizations. See Figure 28.1 for a simple example of applying UML activity diagrams to business process modeling. To show the process model for my shipping client would fill an entire wall!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          数据流建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Data Flow Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          从 1970 年代开始,数据流图 (DFD) 成为可视化软件系统流程中涉及的主要步骤和数据的流行方式。这与业务流程建模不同;相反,DFD 通常用于显示计算机系统中的数据流,尽管它们在理论上可以应用于业务流程建模。DFD 对于记录主要数据流或探索数据流方面的新高级设计非常有用。有关经典 Gane-Sarson 表示法中的 DFD 示例,请参见图 28.2。请注意,流程步骤已编号,以指示顺序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting in the 1970s, data flow diagrams (DFD) became a popular way to visualize the major steps and data involved in software system processes. This is not the same as business process modeling; rather, DFDs were usually used to show data flows in a computer system, although they could in theory be applied to business process modeling. DFDs were useful to document the major data flows or to explore a new high-level design in terms of data flow. See Figure 28.2 for an example DFD in the classic Gane-Sarson notation. Observe that the process steps are numbered, to indicate order.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 28.2.采用 Gane-Sarson 表示法的经典 DFD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在 DFD 中建模的信息对于文档和发现都很有用,但 UML 不包括 DFD 表示法。幸运的是,UML 活动图可以满足相同的目标,它们可以用于数据流建模,取代传统的 DFD 表示法。图 28.3 说明了与图 28.2 中的 DFD 相同的信息,但使用的是 UML 活动图。请注意,除了对象节点可用于显示数据流之外,UML 数据存储节点也适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The information modeled in a DFD is useful, both for documentation and discovery, but the UML does not include DFD notation. Fortunately, UML activity diagrams can satisfy the same goalsthey can be used for data flow modeling, replacing traditional DFD notation. Figure 28.3 illustrates the same information as the DFD in Figure 28.2, but using a UML activity diagram. Notice that in addition to object nodes being useful to show data flow, the UML datastore node is applicable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 28.3.应用活动图表示法来显示数据流模型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          并发编程和并行算法建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Concurrent Programming and Parallel Algorithm Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          尽管细节超出了本介绍的范围,但并发编程问题中的并行算法涉及多个分区以及 fork 和 join 行为。例如,此类算法用于具有有限元或有限差分建模的 3D 仿真,并应用于油藏建模、材料应力分析和天气建模。整个物理空间被细分为多个大块,并且执行许多并行线程(或进程),每个子块一个。在这些情况下,UML 活动图分区可用于表示不同的操作系统线程或进程。对象节点可用于对共享对象和数据进行建模。当然,forking 可用于对多个线程或进程的创建和并行执行进行建模,每个分区一个线程或进程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Although the details are beyond this introduction, parallel algorithms in concurrent programming problems involve multiple partitions, and fork and join behavior. For example, such algorithms are used in 3D simulations with finite element or finite difference modeling, and are applied to oil reservoir modeling, materials stress analysis, and weather modeling. The overall physical space is subdivided into large blocks, and many parallel threads (or processes) execute, one for each sub-block. In these cases the UML activity diagram partitions can be used to represent different operating system threads or processes. The object nodes can be used to model the shared objects and data. And of course, forking can be used to model the creation and parallel execution of multiple threads or processes, one per partition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            28.3. 更多 UML 活动图表示法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            28.3. More UML Activity Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如何显示一个活动在另一个活动图中被展开?图 28.4图 28.5 说明了使用 rake 符号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How to show that an activity is expanded in another activity diagram? Figure 28.4 and Figure 28.5 illustrate, using the rake symbol.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 28.4.活动将在另一个关系图中展开。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 28.5.活动的扩展。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如何显示条件分支?参见图 28.5 中使用的决策符号。相关的合并符号显示流如何重新聚集在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How to show conditional branches? See the decision symbol used in Figure 28.5. The related merge symbol shows how flows can come back together.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            信号如图 28.6 所示。例如,当您需要对事件进行建模(例如触发操作的时间或取消请求)时,它们非常有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Signals are shown in Figure 28.6. They are useful, for example, when you need to model events such as time triggering an action, or a cancellation request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 28.6.信号。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            还有更多可用的 UML 活动表示法。这个简短的介绍只是强调了一些最常见的元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            There's a lot more UML activity notation available. This short introduction merely highlights some of the most common elements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              28.4. 准则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              28.4. Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              活动建模中出现了一些准则;这些包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A few guidelines have emerged in activity modeling; these include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 事实证明,这种技术对于通常涉及多方的非常复杂的流程最有价值。用例文本足以满足简单的流程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • This technique proves most valuable for very complex processes, usually involving many parties. Use-case text suffices for simple processes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 如果对业务流程进行建模,请利用 “rake” 表示法和子活动图。在第一个概览 “level 0” 图上,将所有操作保持在非常高的抽象级别,以便图简短而甜美。在 “level 1” 级别扩展子图中的细节,甚至可能在 “level 2” 级别扩展更多,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • If modeling a business process, take advantage of the "rake" notation and sub-activity diagrams. On the first overview "level 0" diagram, keep all the actions at a very high level of abstraction, so that the diagram is short and sweet. Expand the details in sub-diagrams at the "level 1" level, and perhaps even more at the "level 2" level, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 与上述内容相关,努力使图中动作节点的抽象级别大致相等。作为一个糟糕的反例,假设在 “level 0” 图中有一个标记为 “Deliver Order” 的 action 节点。第二个操作节点 “Calculate Tax”。这些是非常不同的抽象层次。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Related to the above, strive to make the level of abstraction of action nodes roughly equal within a diagram. As a poor counter-example, suppose in a "level 0" diagram there is an action node labeled "Deliver Order." And, a second action node "Calculate Tax." Those are very different levels of abstraction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                28.5. 示例:NextGen 活动图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                28.5. Example: NextGen Activity Diagram

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 28.7 中的部分模型演示了将 UML 应用于 Process Sale 用例流程。为了完整起见,我已经展示了这个案例研究示例,但实际上我不会费心创建这个,因为用例文本和流程的相对简单性使其具有边际价值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The partial model in Figure 28.7 illustrates applying the UML to the Process Sale use case process. I've shown this case-study example for completeness, but in reality would not bother to create this, as the use case text and relative simplicity of the process make it of marginal value.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 28.7.使用活动图对 Process Sale 用例进行建模。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  28.6. 流程:UP 中的活动图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  28.6. Process: Activity Diagrams in the UP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UP 学科之一是业务建模;其目的是理解和传达“要在其中部署系统的组织的结构和动态” [RUP]。业务建模学科的一个关键工件是业务对象模型(UP 域模型的超集),它本质上是使用 UML 类、序列和活动图来可视化业务的工作方式。因此,活动图特别适用于 UP 的业务建模学科。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  One of the UP disciplines is Business Modeling; its purpose is to understand and communicate "the structure and the dynamics of the organization in which a system is to be deployed" [RUP]. A key artifact of the Business Modeling discipline is the Business Object Model (a superset of the UP Domain Model), which essentially visualizes how a business works, using UML class, sequence, and activity diagrams. Thus, activity diagrams are especially applicable within the Business Modeling discipline of the UP.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    28.7. 背景

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    28.7. Background

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    大量的流程建模和数据流图语言自古以来就存在。每年,UML 活动图作为通用标准变得越来越流行,尽管仍然存在很大的变化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A plethora of process modeling and data flow diagramming languages have been around since forever. Each year, UML activity diagrams become more popular as a common standard, though there is still significant variation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    活动图的语义松散地基于 Petri 网,这是计算机科学中的一个重要计算理论。Petri 网的隐喻实现是有标记流经活动图。例如,当令牌到达操作节点时,它会执行。当所有必需的输入令牌到达联接时,将创建输出令牌。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The semantics of activity diagrams are loosely based on Petri nets, an important computational theory in computer science. The metaphoror actualizationof Petri nets is that there are tokens flowing through the activity graph. For example, when a token arrives at an action node, it executes. When all the required input tokens arrive at a join, an output token is created.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第 29 章.UML 状态机图和建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chapter 29. UML State Machine Diagrams and Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      不,不,你不是在思考,你只是在逻辑上。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      尼尔斯·玻尔

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      No, no, you're not thinking, you're just being logical.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Niels Bohr

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 介绍 UML 状态机图表示法、示例和各种建模应用程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Introduce UML state machine diagram notation, with examples, and various modeling applications.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        与活动图一样,UML 状态图显示动态视图。UML 包含表示法,用于说明事物的事件和状态事务、用例、人员等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As with activity diagrams, UML state diagrams show a dynamic view. The UML includes notation to illustrate the events and states of thingstransactions, use cases, people, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        显示了最重要的符号特征,但本介绍中未涵盖许多罕见元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The most important notational features are shown, but there are many rare elements not covered in this introduction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          29.1. 示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          29.1. Example

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如图 29.1 所示,UML 状态机图说明了对象的有趣事件和状态,以及对象对事件的反应行为。过渡显示为箭头,并标有其事件。状态以圆角矩形显示。通常包含一个初始伪状态,该状态在创建实例时自动转换为另一个状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A UML state machine diagram, as shown in Figure 29.1, illustrates the interesting events and states of an object, and the behavior of an object in reaction to an event. Transitions are shown as arrows, labeled with their event. States are shown in rounded rectangles. It is common to include an initial pseudo-state, which automatically transitions to another state when the instance is created.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 29.1.电话的状态机图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          状态机图显示对象的生命周期:它经历的事件、它的转换以及它在这些事件之间所处于的状态。它不需要说明所有可能的事件;如果出现图中未表示的事件,则就状态机图而言,该事件将被忽略。因此,我们可以根据需要创建一个状态机图,以任意简单或复杂的细节级别描述对象的生命周期。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A state machine diagram shows the lifecycle of an object: what events it experiences, its transitions, and the states it is in between these events. It need not illustrate every possible event; if an event arises that is not represented in the diagram, the event is ignored as far as the state machine diagram is concerned. Therefore, we can create a state machine diagram that describes the lifecycle of an object at arbitrarily simple or complex levels of detail, depending on our needs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            29.2. 定义:事件、状态和转换

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            29.2. Definitions: Events, States, and Transitions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            事件是重大或值得注意的事件。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            An event is a significant or noteworthy occurrence. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 电话接收器被解开。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • A telephone receiver is taken off the hook.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            状态是对象在某一时刻的状态事件之间的时间。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A state is the condition of an object at a moment in timethe time between events. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 电话在将接收器置于挂机上后处于“空闲”状态,直到它从挂机上取下。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • A telephone is in the state of being "idle" after the receiver is placed on the hook and until it is taken off the hook.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            转换是两种状态之间的关系,它指示当事件发生时,对象从前一状态移动到后一状态。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A transition is a relationship between two states that indicates that when an event occurs, the object moves from the prior state to the subsequent state. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 当事件发生“摘机”时,将电话从“空闲”状态转换为“活动”状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • When the event "off hook" occurs, transition the telephone from the "idle" to "active" state.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              29.3. 如何应用状态机图?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              29.3. How to Apply State Machine Diagrams?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              State-Independent 和 State-Dependent 对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              State-Independent and State-Dependent Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如果对象始终以相同的方式响应事件,则认为它相对于该事件是独立于状态的(或无模式的)。例如,如果一个对象收到一条消息,并且响应方法总是执行相同的操作。该对象与该消息的状态无关。如果对于所有感兴趣的事件,一个对象总是以相同的方式做出反应,那么它是一个与状态无关的对象。相比之下,依赖于状态的对象根据其状态或模式对事件做出不同的反应。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              If an object always responds the same way to an event, then it is considered state-independent (or modeless) with respect to that event. For example, if an object receives a message, and the responding method always does the same thing. The object is state-independent with respect to that message. If, for all events of interest, an object always reacts the same way, it is a state-independent object. By contrast, state-dependent objects react differently to events depending on their state or mode.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对于具有复杂行为的状态依赖对象,请考虑使用状态机,而不是针对与状态无关的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Consider state machines for state-dependent objects with complex behavior, not for state-independent objects.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,电话在很大程度上依赖于状态。手机对按下特定按钮(生成事件)的反应取决于 phoneoff hook、engaged、configuration subsystem 中的当前模式,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, a telephone is very state-dependent. The phone's reaction to pushing a particular button (generating an event) depends on the current mode of the phoneoff hook, engaged, in a configuration subsystem, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              正是对于这些复杂的、依赖于状态的问题,状态机图可能会为理解或记录某些内容增加价值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It's for these kind of complex state-dependent problems that a state machine diagram may add value to either understand or document something.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              通常,业务信息系统几乎没有复杂的依赖于状态的类。应用状态机建模很少有帮助。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In general, business information systems have few complex state-dependent classes. It is seldom helpful to apply state machine modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              相比之下,进程控制、设备控制、协议处理程序和电信域通常具有许多依赖于状态的对象。如果您在这些领域工作,请务必了解并考虑状态机建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              By contrast, process control, device control, protocol handlers, and telecommunication domains often have many state-dependent objects. If you work in these domains, definitely know and consider state machine modeling.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对状态相关对象进行建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Modeling State-dependent Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              从广义上讲,状态机以两种方式应用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Broadly, state machines are applied in two ways:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. 对响应事件的复杂响应式对象的行为进行建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. To model the behavior of a complex reactive object in response to events.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              3. 对合法的操作序列进行建模协议或语言规范。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 如果 “对象” 是一种语言、协议或进程,则此方法可以被视为 #1 的特化。上下文无关语言的正式语法是一种状态机。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              4. To model legal sequences of operationsprotocol or language specifications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • This approach may be considered a specialization of #1, if the "object" is a language, protocol, or process. A formal grammar for a context-free language is a kind of state machine.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              以下是通常与状态相关的常见对象列表,对于这些对象,创建状态机图可能很有用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The following is a list of common objects which are often state-dependent, and for which it may be useful to create a state machine diagram:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Complex Reactive 对象
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 由软件控制的物理设备

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 手机、汽车、微波炉:他们对事件有复杂而丰富的反应,而这种反应取决于他们当前的模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Physical Devices controlled by software

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Phone, car, microwave oven: They have complex and rich reactions to events, and the reaction depends upon their current mode.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 事务和相关业务对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 业务对象(销售、订单、付款)对事件有何反应?例如,如果发生 cancel 事件,Order 会发生什么情况?了解包裹在运输业务中可能经历的所有事件和状态有助于设计、验证和流程改进。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Transactions and related Business Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How does a business object (a sale, order, payment) react to an event? For example, what should happen to an Order if a cancel event occurs? And understanding all the events and states that a Package can go through in the shipping business can help with design, validation, and process improvement.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 角色 mutator这些是更改其角色的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A 平民转变为退伍军人的人。每个角色都由一个状态表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Role MutatorsThese are objects that change their role.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A Person changing roles from being a civilian to a veteran. Each role is represented by a state.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              协议和法律序列
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 通信协议

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • TCP 和新协议可以通过状态机图轻松清晰地理解。该图说明了操作何时合法。例如,如果协议处理程序已处于 “closed” 状态,则应忽略 TCP“close”请求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Communication Protocols

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • TCP, and new protocols, can be easily and clearly understood with a state machine diagram. The diagram illustrates when operations are legal. For example, a TCP "close" request should be ignored if the protocol handler is already in the "closed" state.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • UI 页面/窗口流或导航在进行 UI 建模时,了解 Web 页面或窗口之间的法律顺序可能很有用;这通常很复杂。状态机是模拟 UI 导航的绝佳工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • UI Page/Window Flow or NavigationWhen doing UI modeling, it can be useful to understand the legal sequence between Web pages or windows; this is often complex. A state machine is a great tool to model UI navigation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • UI 流控制器或会话这与 UI 导航建模有关,但特别关注控制页面流的服务器端对象。这些通常是服务器端对象,表示正在进行的会话或与 Client 端的对话。例如,一个 Web 应用程序,它记住与 Web 客户端的会话状态,并根据会话的状态和接收的下一个操作控制到新网页的转换或当前网页的修改显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • UI Flow Controllers or SessionsThis is related to UI navigation modeling, but specifically focused on the server-side object that controls page flow. These are usually server-side objects representing an ongoing session or conversations with a client. For example, a Web application that remembers the state of the session with a Web client and controls the transitions to new Web pages, or the modified display of the current Web page, based upon the state of the session and the next operation that is received.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 使用案例 系统操作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 您是否还记得 Process Sale 的系统操作:makeNewSale、enterItem 等?这些应该以合法顺序到达;例如,endSale 应仅在一个或多个 enterItem 操作之后出现。通常,顺序是显而易见的,但如果复杂,状态机可以对此进行建模,将用例本身视为一个对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Use Case System Operations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Do you recall the system operations for Process Sale: makeNewSale, enterItem, and so forth? These should arrive in a legal order; for example, endSale should only come after one or more enterItem operations. Usually, the order is trivially obvious, but if complex, a state machine can model this, treating the use case itself as an object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 单个 UI 窗口事件处理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 了解一个窗口或表单的事件和法律序列。例如,仅当“剪贴板”中有要粘贴的内容时,“编辑-粘贴”操作才有效。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Individual UI Window Event Handling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Understanding the events and legal sequences for one window or form. For example, the Edit-Paste action is only valid if there is something in the "clipboard" to paste.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                29.4. 更多 UML 状态机图表示法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                29.4. More UML State Machine Diagram Notation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                转换操作和守卫

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Transition Actions and Guards

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                转换可能会导致操作触发。在软件实现中,这可能表示对状态机图类方法的调用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A transition can cause an action to fire. In a software implementation, this may represent the invocation of a method of the class of the state machine diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                一个 transition 也可能有一个 conditional guardor boolean test。仅当测试通过时,才会发生转换。参见图 29.2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A transition may also have a conditional guardor boolean test. The transition only occurs if the test passes. See Figure 29.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 29.2.Transition action 和 guard 表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                嵌套状态

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Nested States

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                状态允许嵌套包含子状态;子状态继承其超状态(封闭状态)的转换。参见图 29.3。这是 UML 所基于的 Harel 状态图方法的一个关键贡献,因为它导致了简洁的状态机图。可以通过将子状态嵌套在超状态框中来以图形方式显示子状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A state allows nesting to contain substates; a substate inherits the transitions of its superstate (the enclosing state). See Figure 29.3. This was a key contribution of the Harel statechart approach that the UML is based on, as it leads to succinct state machine diagrams. Substates may be graphically shown by nesting them in a superstate box.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 29.3.嵌套状态。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如,当转换到 Active 状态时,将创建并转换到 PlayingDialTone 子状态。无论对象处于哪个子状态,如果发生与 Active 超状态相关的挂机事件,则会转换为 Idle 状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For example, when a transition to the Active state occurs, creation and transition into the PlayingDialTone substate occurs. No matter what substate the object is in, if the on hook event related to the Active superstate occurs, a transition to the Idle state occurs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  29.5. 示例:使用状态机进行 UI 导航建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  29.5. Example: UI Navigation Modeling with State Machines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  某些 UI 应用程序(尤其是 Web UI 应用程序)具有复杂的页面流。状态机是记录这一点的好方法,以便于理解,也是在创意设计过程中对页面流进行建模的好方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Some UI applications, especially Web UI applications, have complex page flows. State machines are a great way to document that, for understanding, and a great way to model page flows, during creative design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UI 敏捷建模和 UI 原型设计中的一种常见技术是对墙壁上有大纸片的 UI 进行建模。每个工作表代表一个网页。便利贴放置在图纸上以表示元素;也许 yellow 是信息,pink 是控件,例如 button。每张表格都带有标签,例如“帮助页面”、“产品页面”等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A common technique in UI agile modeling and UI prototyping is to model a UI with large paper sheet on walls. Each sheet represents a Web page. Post-it notes are place on the sheets to represent elements; perhaps yellow is information and pink is a control, such as a button. Each sheet is labeled, e.g., "Help Page," "Product Page," and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  除了使用这种 “low tech, high touch” 方法对页面内容进行建模之外,对这些页面之间的流进行建模也很有用。因此,在靠近网页墙的白板上,我将绘制一个 UML 状态机图。状态表示页面,事件表示导致从一个页面传输到另一个页面的事件,例如按钮单击。有关此 UI 导航模型的示例,请参见图 29.4。当然,这个小例子并不能公正地评价这种做法的有用性;它的价值对于大型、复杂的页面结构来说变得显而易见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In addition to modeling the page content with this "low tech, high touch" method, it is useful to model the flow between these pages. Therefore, on a whiteboard adjacent to the wall of Web pages, I'll sketch a UML state machine diagram. The states represent the pages and the events represent the events that cause transfer from one page to another, such as a button click. See Figure 29.4 for an example of this UI navigation model. Of course, this small example doesn't do justice to the usefulness of the practice; it's value becomes evident for large, complex page structures.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 29.4.将状态机应用于 Web 页面导航建模。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    29.6. 示例:NextGen 用例状态机图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    29.6. Example: NextGen Use Case State Machine Diagram

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    案例研究中没有真正有趣的复杂响应式对象,因此我将演示一个状态机图来显示用例操作的合法顺序。参见图 29.5 了解它在 Process Sale 用例中的应用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    There are no really interesting complex reactive objects in the case studies, so I'll illustrate a state machine diagram to show legal sequencing of use case operation. See Figure 29.5 for its application to the Process Sale use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 29.5.用于使用案例操作的法律序列的示例状态机。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      29.7. 流程:UP 中的状态机图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      29.7. Process: State Machine Diagrams in the UP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UP 中没有一种称为“州模型”的模型。相反,任何模型(设计模型、域模型、业务对象模型等)中的任何元素都可能具有状态机,以更好地理解或传达其响应事件的动态行为。例如,与设计模型的 Sale 设计类关联的状态机本身就是设计模型的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There is not one model in the UP called the "state model." Rather, any element in any model (Design Model, Domain Model, Business Object Model, and so forth) may have a state machine to better understand or communicate its dynamic behavior in response to events. For example, a state machine associated with the Sale design class of the Design Model is itself part of the Design Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        29.8. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        29.8. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Cook 和 Daniels 的 Designing Object Systems 中详细介绍了状态模型在 OOA/D 中的应用。Douglass 的 Real Time UML 也对状态建模进行了很好的讨论;内容强调实时系统,但适用范围广泛。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The application of state models to OOA/D is well-covered in Designing Object Systems by Cook and Daniels. Real Time UML by Douglass also provides an excellent discussion of state modeling; the content emphasizes real-time systems, but is broadly applicable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          第 30 章.关联用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Chapter 30. Relating Use Cases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          为什么程序员把万圣节和圣诞节混在一起了?因为 OCT(31) = DEC(25)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Why do programmers get Halloween and Christmas mixed up? Because OCT(31) = DEC(25)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 将用例与文本和图表格式的 includeextend 关联相关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Relate use cases with include and extend associations, in both text and diagram formats.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            用例可以相互关联。例如,Handle Credit Payment 等子功能使用案例可能是多个常规使用案例的一部分,例如 Process SaleProcess Rental。将用例组织到关系中不会影响系统的行为或要求。相反,它只是一种组织机制,用于(理想情况下)改善用例的沟通和理解,减少文本重复,并改进用例文档的管理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use cases can be related to each other. For example, a subfunction use case such as Handle Credit Payment may be part of several regular use cases, such as Process Sale and Process Rental. Organizing use cases into relationships has no impact on the behavior or requirements of the system. Rather, it is simply an organization mechanism to (ideally) improve communication and comprehension of the use cases, reduce duplication of text, and improve management of the use case documents.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            指南:避免为用例关系而苦恼

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Guideline: Avoid Agonizing Over Use Case Relationships

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在一些使用用例的组织中,太多的非生产性时间花在争论如何在用例图中关联用例上,而不是重要的用例工作:编写文本。它实际上反映了软件项目中面向分析的工作中一个更深层次的问题:在低价值分析和建模上浪费了太多时间。这是瀑布思维而不是迭代和进化思维更大问题的一部分;如果您认为自己必须在一开始就 “把事情做对”,那么一切都会陷入分析瘫痪。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In some organizations working with use cases, way too much unproductive time is spent debating how to relate use cases in a use case diagram, rather than the important use case work: writing text. It actually a reflects a deeper problem in analysis-oriented work on software projects: Too much time wasted on low-value analysis and modeling. It's part of the larger problem of waterfall thinking rather than iterative and evolutionary thinking; if you think you have to "get it right" at the start, everything becomes bogged down in analysis paralysis.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            因此,尽管本章讨论了相关的用例,但应该正确看待这个主题及其工作:它有一定的价值,但重要的工作是编写用例文本。指定需求是通过编写文本来完成的,而不是通过组织用例一个可选步骤,可能会提高他们的理解力或减少重复。如果团队通过花费数小时(或者更糟糕的是,数天)讨论用例图和用例关系来开始用例建模(“应该是包含关系还是扩展关系?我们应该专门讨论这个用例吗?“),而不是快速专注于编写关键的用例文本,相对努力是错误的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Consequently, although this chapter discusses relating use cases, the subject and its effort should be put in perspective: It has some value, but the important work is writing use case text. Specifying the requirements is done by writing text, not by organizing use casesan optional step to possibly improve their comprehension or reduce duplication. If a team starts off use-case modeling by spending hours (or worse, days) discussing a use case diagram and use case relationships ("Should that be an include or an extend relationship? Should we specialize this use case?"), rather than quickly focusing on writing the key use case text, relative effort was misplaced.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            此外,在 UP 和其他迭代方法中,将用例组织成关系可以在细化阶段以小步骤迭代发展;在项目开始时,尝试在接近项目的一个步骤中完全定义和完善完整的用例图和一组关系,这无济于事。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Plus, in the UP and other iterative methods, the organization of use cases into relationships can iteratively evolve in small steps over the elaboration phase; it is not helpful to attempt a waterfall-like effort of fully defining and refining a complete use case diagram and set of relationships in one step near the start of a project.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              30.1. include 关系

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              30.1. The include Relationship

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这是最常见和最重要的关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is the most common and important relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              一些部分行为在多个使用案例中很常见。例如,按贷款付款的描述出现在多个使用案例中,包括 Process Sale、Process Rental、Contribute to Lay-away Plan 等。与其重复此文本,不如将其分离到自己的子函数用例中,并指示其包含。这只是重构和链接文本以避免重复。[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It is common to have some partial behavior that is common across several use cases. For example, the description of paying by credit occurs in several use cases, including Process Sale, Process Rental, Contribute to Lay-away Plan, and so forth. Rather than duplicate this text, it is desirable to separate it into its own subfunction use case, and indicate its inclusion. This is simply refactoring and linking text to avoid duplication.[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [1] 如果链接也使用可导航的超链接实现,这将很有帮助。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [1] It is helpful if the links are implemented with navigable hyperlinks as well.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UC1:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1.客户到达 POS 收银台,并携带要购买的商品和/或服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1.Customer arrives at a POS checkout with goods and/or services to purchase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7.客户支付,系统处理支付。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7.Customer pays and System handles payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7b.Paid by credit (使用信用支付):包括 Handle credit payment(处理信用支付)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7c.通过支票支付:包括 Handle check payment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7b. Paying by credit: Include Handle Credit Payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7c. Paying by check: Include Handle Check Payment.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UC7:流程租赁

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              6b.Paid by credit (使用信用支付):包括 Handle credit payment(处理信用支付)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              6b. Paying by credit: Include Handle Credit Payment.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UC12:处理信用支付

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              水平:子功能

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Level: Subfunction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. 客户输入其信用账户信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. Customer enters their credit account information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              3. 系统向外部 Payment Authorization Service System 发送支付授权请求,并请求支付审批。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              4. System sends payment authorization request to an external Payment Authorization Service System, and requests payment approval.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              5. 系统收到付款批准并向出纳发出批准信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              6. System receives payment approval and signals approval to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2a.系统检测到与外部系统协作失败:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. 系统向收银员发出错误信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. 收银员要求客户进行替代付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2a. System detects failure to collaborate with external system:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1. System signals error to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2. Cashier asks Customer for alternate payment.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这就是 include 关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is the include relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              一个稍短(因此可能是首选的)表示法来表示包含的用例,只是为了给它加下划线或以某种方式突出显示它。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A slightly shorter (and thus perhaps preferred) notation to indicate an included use case is simply to underline it or highlight it in some fashion. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UC1:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7b.Paid by credit (使用信用支付):处理 Credit Payment(信用支付)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7c.通过支票支付:处理支票支付

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7b. Paying by credit: Handle Credit Payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              7c. Paying by check: Handle Check Payment.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              请注意,Handle Credit Payment 子函数使用案例最初位于 Process Sale 使用案例的 Extensions 部分中,但为避免重复而被排除在外。另请注意,子功能用例中使用的 Main SuccessExtensions 结构与常规基本业务流程用例(如 Process Sale)中使用相同的结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Notice that the Handle Credit Payment subfunction use case was originally in the Extensions section of the Process Sale use case, but was factored out to avoid duplication. Also note that the same Main Success and Extensions structures are used in the subfunction use case as in the regular elementary business process use cases such as Process Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Fowler [Fowler03] 提供了一个关于何时使用 include 关系的简单实用指南:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A simple, practical guideline of when to use the include relationship is offered by Fowler [Fowler03]:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              当您在两个或多个单独的用例中重复自己,并且希望避免重复时,请使用 include

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Use include when you are repeating yourself in two or more separate use cases and you want to avoid repetition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              另一个动机是简单地将一个非常长的用例分解为子单元以提高理解力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Another motivation is simply to decompose an overwhelmingly long use case into subunits to improve comprehension.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              将 include 与异步事件处理一起使用

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Using include with Asynchronous Event Handling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              此外,include 关系的另一种用途是描述异步事件的处理,例如,当用户能够随时选择或分支到特定窗口、函数或 Web 页时,或者在一系列步骤中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Yet another use of the include relationship is to describe the handling of an asynchronous event, such as when a user is able to, at any time, select or branch to a particular window, function, or Web page, or within a range of steps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              事实上,在第 6 章的用例介绍中已经探讨了支持这种异步分支的用例表示法,但当时没有讨论添加对包含的子用例的调用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In fact, the use case notation to support this asynchronous branching was already explored in the introduction to use cases in Chapter 6, but at that time the addition of calling out to an included sub-use case was not discussed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              基本表示法是在 Extensions 部分中使用 a*、b*、... 样式标签。回想一下,这些意味着随时可能发生的扩展或事件。一个小的变体是范围标签,例如 3-9,当异步事件可能发生在相对较大的用例步骤范围内(但不是全部)时,将使用该标签。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The basic notation is to use the a*, b*, ... style labels in the Extensions section. Recall that these imply an extension or event that can happen at any time. A minor variation is a range label, such as 3-9, to be used when the asynchronous event can occur within a relatively large range of the use case steps, but not all.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UC1:进程 FooBars

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              一个*。客户可以随时选择编辑个人信息:编辑个人信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              a*. At any time, Customer selects to edit personal information: Edit Personal Information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              b*.客户可以随时选择打印帮助:Present Printing Help

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              b*. At any time, Customer selects printing help: Present Printing Help.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2-11. 客户取消:取消交易确认

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2-11. Customer cancels: Cancel Transaction Confirmation.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Summary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              include 关系可用于大多数用例关系问题。总结一下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The include relationship can be used for most use case relationship problems. To summarize:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在以下情况下,请分解出子函数使用案例并使用 include 关系:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Factor out subfunction use cases and use the include relationship when:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 它们在其他使用案例中是重复的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • They are duplicated in other use cases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 用例非常复杂且冗长,将其划分为子单元有助于理解。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • A use case is very complex and long, and separating it into subunits aids comprehension.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              正如将要解释的,还有其他关系:扩展和泛化。但是,专家用例建模者 Cockburn 建议首选 include 关系,而不是 extend 或 generalization:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As will be explained, there are other relationships: extend and generalization. But Cockburn, an expert use-case modeler, advises to prefer the include relationship over extend or generalization:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              作为第一条经验法则,请始终使用用例之间的 include 关系。遵循此规则的人报告说,与混合使用 includeextendgeneralizes [Cockburn01] 的人相比,他们和他们的读者对他们的写作的困惑更少。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As a first rule of thumb, always use the include relationship between use cases. People who follow this rule report they and their readers have less confusion with their writing than people who mix include with extend and generalizes [Cockburn01].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                30.2. 术语:具体、抽象、基础和附加用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                30.2. Terminology: Concrete, Abstract, Base, and Addition Use Cases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                一个具体的用例由一个 actor 发起,并执行 actor 所需的整个行为 [RUP]。这些是基本的业务流程用例。例如,Process Sale 就是一个具体的用例。相比之下,抽象用例永远不会自行实例化;它是一个子函数使用案例,是另一个使用案例的一部分。处理信用支付是抽象的;它不是独立的,而是始终是另一个故事的一部分,例如 Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A concrete use case is initiated by an actor and performs the entire behavior desired by the actor [RUP]. These are the elementary business process use cases. For example, Process Sale is a concrete use case. By contrast, an abstract use case is never instantiated by itself; it is a subfunction use case that is part of another use case. Handle Credit Payment is abstract; it doesn't stand on its own, but is always part of another story, such as Process Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                包含另一个使用案例,或者由另一个使用案例扩展或专门的使用案例的使用案例称为基本使用案例Process Sale 是包含的 Handle Credit Payment 子功能用例的基本用例。另一方面,作为包含、扩展或特化的使用案例称为 附加使用案例Handle Credit Payment 是与 Process Sale 的 include 关系中的附加用例。附加用例通常是抽象的。基本用例通常是具体的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A use case that includes another use case, or that is extended or specialized by another use case is called a base use case. Process Sale is a base use case with respect to the included Handle Credit Payment subfunction use case. On the other hand, the use case that is an inclusion, extension, or specialization is called an addition use case. Handle Credit Payment is the addition use case in the include relationship to Process Sale. Addition use cases are usually abstract. Base use cases are usually concrete.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  30.3. extend 关系

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  30.3. The extend Relationship

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  假设由于某种原因,用例的文本不应被修改(至少不应被修改)。也许使用无数新的扩展和条件步骤不断修改用例是一个令人头疼的维护问题,或者该用例已被基线化为稳定构件,无法触及。如何在不修改其原始文本的情况下附加到用例中?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Suppose a use case's text should not be modified (at least not significantly) for some reason. Perhaps continually modifying the use case with myriad new extensions and conditional steps is a maintenance headache, or the use case has been baselined as a stable artifact, and can't be touched. How to append to the use case without modifying its original text?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  extend 关系提供了一个答案。这个想法是创建一个扩展或添加用例,并在其中描述它在何处以及在什么条件下扩展某些基本用例的行为。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The extend relationship provides an answer. The idea is to create an extending or addition use case, and within it, describe where and under what condition it extends the behavior of some base use case. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UC1:流程销售(基本用例)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  分机积分:VIP 客户,第 1 步。付款,第 7 步。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extension Points: VIP Customer, step 1. Payment, step 7.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1.客户到达 POS 收银台,并携带要购买的商品和/或服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1.Customer arrives at a POS checkout with goods and/or services to purchase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7.客户支付,系统处理支付。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7.Customer pays and System handles payment.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UC15:处理礼品券付款(扩展用例)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  触发器:客户希望使用礼品券付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Trigger: Customer wants to pay with gift certificate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  扩展点:付款在制品销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extension Points: Payment in Process Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  水平:子功能

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Level: Subfunction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 客户将礼券交给收银员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Customer gives gift certificate to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 收银员输入礼品证书 ID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Cashier enters gift certificate ID.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这是扩展关系的一个示例。请注意,使用了扩展点,并且扩展用例是由某些条件触发的。扩展点是基本用例中的标签,扩展用例将其引用为扩展点,因此基本用例的步骤编号可以更改,而不会再次影响扩展用例间接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This is an example of an extend relationship. Note the use of an extension point, and that the extending use case is triggered by some condition. Extension points are labels in the base use case which the extending use case references as the point of extension, so that the step numbering of the base use case can change without affecting the extending use caseindirection yet again.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  有时,扩展点只是 “At any point in use case X”(在用例 X 中的任何点)。这在具有许多异步事件的系统中尤其常见,例如字处理器(“立即进行拼写检查”、“立即进行同义词库查找”)或反应式控制系统。但请注意,如前面的 include 关系部分所述,include 也可用于描述异步事件处理。当基本用例无法修改时,扩展替代方案是一个选项。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sometimes, the extension point is simply "At any point in use case X." This is especially common in systems with many asynchronous events, such as a word processor ("do a spell check now," "do a thesaurus lookup now"), or reactive control systems. Note however, as described in the prior include relationship section, that include can also be used to describe asynchronous event handling. The extend alternative is an option when the base use case is closed to modification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,扩展关系的签名特性是,基本用例 (Process Sale) 不引用扩展用例 (Handle Gift Certificate Payment),因此,不定义或控制扩展触发的条件。流程销售本身是完整和完整的,无需了解扩展用例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Note that a signature quality of the extend relationship is that the base use case (Process Sale) has no reference to the extending use case (Handle Gift Certificate Payment), and therefore, does not define or control the conditions under which the extensions trigger. Process Sale is complete and whole by itself, without knowing about the extending use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,此 Handle Gift Certificate Payment 附加用例也可以在 Process Sale 中使用 include 关系引用,就像 Handle Credit Payment 一样。这通常是合适的。但此示例的动机是 Process Sale 用例不能被修改,在这种情况下,使用 extend 而不是 include。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Observe that this Handle Gift Certificate Payment addition use case could alternatively have been referenced within Process Sale with an include relationship, as with Handle Credit Payment. That is often suitable. But this example was motivated by the constraint that the Process Sale use case was not to be modified, which is the situation in which to use extend rather than include.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此外,请注意,此礼品证书方案可以通过将其添加为 Process SaleExtensions 部分中的扩展来简单地记录。此方法避免了 include 和 extend 关系,也避免了创建单独的子函数使用案例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Further, note that this gift certificate scenario could simply have been recorded by adding it as an extension in the Extensions section of Process Sale. This approach avoids both the include and extend relationships, and the creation of a separate subfunction use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  事实上,只更新 Extensions 部分通常是首选解决方案,而不是创建复杂的用例关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Indeed, just updating the Extensions section is usually the preferred solution, rather than creating complex use case relationships.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  一些使用案例指南建议使用扩展使用案例和扩展关系来对插入到基本使用案例中的条件或可选行为进行建模。这并不准确,但它忽略了一点,即可选和条件行为可以简单地记录为基本用例的 Extensions 部分中的文本。使用 extend 关系和更多用例的复杂性不仅仅是由可选行为驱动的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Some use case guidelines recommend using extending use cases and the extend relationship to model conditional or optional behavior inserted into the base use case. This is not inaccurate, but it misses the point that optional and conditional behavior can simply be recorded as text in the Extensions section of the base use case. The complication of using the extend relationship and more use cases is not motivated only by optional behavior.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  使用 extend 技术最实际的动机是当由于某种原因而不希望修改基本用例时。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What most practically motivates using the extend technique is when it is undesirable for some reason to modify the base use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    30.4. generalize 关系

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    30.4. The generalize Relationship

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    对 generalize 关系的讨论超出了本介绍的范围。但是,请注意,用例专家在没有这种可选关系的情况下成功地完成了用例工作,这为用例增加了另一个级别的复杂性,并且从业者尚未就如何从这个想法中获得价值的最佳实践指南达成一致。使用案例顾问的一个常见观察是,这会导致复杂性,并且将非生产性时间花费在添加许多使用案例关系上。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discussion of the generalize relationship is outside the scope of this introduction. However, note that use case experts have been successfully doing use case work without this optional relationship, which adds another level of complexity to use cases, and there is not yet agreement by practitioners on the best-practice guidelines of how to get value from this idea. A common observation by use case consultants is that complications result and unproductive time is spent on the addition of many use case relationships.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      30.5. 用例图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      30.5. Use Case Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 30.1 说明了 include 关系的 UML 表示法,这是案例研究中唯一使用的一种,遵循用例专家的建议,使事情变得简单,并更喜欢 include 关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 30.1 illustrates the UML notation for the include relationship, which is the only one being used in the case study, following the advice of use-case experts to keep things simple and prefer the include relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 30.1.Use case include 关系。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      extend 关系表示法如图 30.2 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The extend relationship notation is illustrated in Figure 30.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 30.2.扩展关系。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        第 31 章.更多 SSD 和合同

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Chapter 31. More SSDs and Contracts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        美德是诱惑不足。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        乔治·萧伯纳

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Virtue is insufficient temptation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        George Bernard Shaw

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 定义当前迭代的 SSD 和操作合同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Define SSDs and operation contracts for the current iteration.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          本章快速总结了 NextGen 案例研究的本迭代中对 SSD 和系统操作合同的更新。大富翁问题不需要更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The chapter quickly summarizes updates to SSDs and system operation contracts for this iteration of the NextGen case study. No changes are necessary for the Monopoly problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            31.1. 下一代 POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            31.1. NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            新的 System Sequence Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            New System Sequence Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在当前迭代中,新的付款处理要求涉及与外部系统的新协作。回顾一下,SSD 使用序列图符号来说明系统间的协作,将每个系统视为一个黑盒。为了阐明以下问题,说明 SSD 中的新系统事件非常有用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the current iteration, the new payment handling requirements involve new collaborations with external systems. To review, SSDs use sequence diagram notation to illustrate inter-system collaborations, treating each system as a blackbox. It is useful to illustrate the new system events in SSDs in order to clarify:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • NextGen POS 系统需要支持的新系统操作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • new system operations that the NextGen POS system will need to support

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 对其他系统的调用,以及这些调用的预期响应

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • calls to other systems, and the responses to expect from these calls

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            常见的流程销售开始场景

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            基本场景开始部分的 SSD 包括 makeNewSale、enterItemendSale 系统事件;无论采用何种支付方式,它都是通用的(见图 31.1)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The SSD for the beginning portion of a basic scenario includes makeNewSale, enterItem, and endSale system events; it is common regardless of the payment method (see Figure 31.1).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 31.1.SSD 常见开始。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            信用支付

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            此信用支付场景 SSD 在 common beginning 之后开始(参见图 31.2)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            This credit payment scenario SSD starts after the common beginning (see Figure 31.2).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 31.2.信用支付 SSD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在贷方和支票付款的两种情况下,都做了一个简化的假设(对于此迭代),即付款完全等于销售总额,因此不同的 “tendered” 金额不必是 input 参数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In both cases of credit and check payments, a simplifying assumption is made (for this iteration) that the payment is exactly equal to the sale total, and thus a different "tendered" amount does not have be an input parameter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            请注意,对外部 CreditAuthorizationService 的调用被建模为具有返回值的常规同步消息。这是一个抽象的概念;它可以通过安全 HTTPS 上的 SOAP 请求或任何远程通信机制来实现。在上一个迭代中定义的资源适配器将隐藏特定协议。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Note that the call to the external CreditAuthorizationService is modeled as a regular synchronous message with a return value. This is an abstraction; it could be implemented with a SOAP request over secure HTTPS, or any remote communication mechanism. The resource adapters defined in the prior iteration will hide the specific protocol.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            makeCreditPayment 系统操作和使用案例假设客户的信用信息来自信用卡,因此信用账号和到期日期进入系统(可能通过读卡器)。尽管人们认识到,将来会出现用于通信信用信息的替代机制,但支持信用卡的假设是非常稳定的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The makeCreditPayment system operationand the use caseassume that the credit information of the customer is coming from a credit card, and thus a credit account number and expiry date enter the system (probably via a card reader). Although it is recognized that in the future, alternative mechanisms for communicating credit information will arise, the assumption that credit cards will be supported is very stable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            回想一下,当信用授权服务批准信用付款时,它欠 store 付款;因此,需要将 Receivables 分录添加到 Accounts Receivable System。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Recall that when a credit authorization service approves a credit payment, it owes the store for the payment; thus, a receivables entry needs to be added to the accounts receivable system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            支票付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            支票支付场景的 SSD 如图 31.3 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The SSD for the check payment scenario is shown in Figure 31.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 31.3.支票付款 SSD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            根据用例,收银员必须输入驾驶执照号码进行验证。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            According to the use case, the cashier must enter the driver's license number for validation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            新系统操作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            New System Operations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在此迭代中,我们的系统必须处理的新系统操作是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In this iteration, the new system operations that our system must handle are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeCredit付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeCreditPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeCheck付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • makeCheckPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在第一次迭代中,现金支付的系统操作只是 makePayment。现在,付款的类型不同,它被重命名为 makeCashPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the first iteration, the system operation for the cash payment was simply makePayment. Now that the payments are of different types, it is renamed to makeCashPayment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            新系统操作合同

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            New System Operation Contracts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            回顾一下,系统操作契约是一个可选的需求工件(Use-Case Model 的一部分),它添加了有关系统操作结果的细节。通常,用例文本本身就足够了,这些协定没有用。但有时,它们通过精确和详细的方法带来价值,以识别在系统上调用复杂操作时会发生什么,即域模型中定义的对象的状态更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To review, system operation contracts are an optional requirements artifact (part of the Use-Case Model) that adds fine detail regarding the results of a system operation. Usually, the use case text is itself sufficient, and these contracts aren't useful. But on occasion they bring value by their precise and detailed approach to identifying what happens when a complex operation is invoked on the system, in terms of state changes to objects defined in the Domain Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            以下是新系统操作的合同:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Here are contracts for the new system operations:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            CO5 合约:makeCreditPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            makeCreditPayment( 信用账户编号, 到期日期 )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            makeCreditPayment( creditAccountNumber, expiryDate )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            存在正在进行的销售,所有物品都已输入

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            An underway sale exists and all items have been entered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 创建了 CreditPayment pmt

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a CreditPayment pmt was created

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt 与当前的 Sale 销售相关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt was associated with the current Sale sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 创建了 CreditCard 抄送;cc.number = 信用账户编号, cc.expiryDate = 到期日期

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a CreditCard cc was created; cc.number = creditAccountNumber, cc.expiryDate = expiryDate

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - CC 与 PMT 相关

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - cc was associated with pmt

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 已创建 CreditPaymentRequest cpr

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a CreditPaymentRequest cpr was created

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - PMT 与 CPR 相关

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt was associated with cpr

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 创建了 ReceivableEntry re

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a ReceivableEntry re was created

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - re 与外部 AccountsReceivable 相关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - re was associated with the external AccountsReceivable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 促销作为已完成的销售与品牌旗舰店相关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - sale was associated with the Store as a completed sale



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            请注意指示 Accounts Receivable 中新 Receivable 分录的关联后的后置条件。虽然这项责任超出了 NextGen 系统的范围,但应收账款系统在企业的控制范围内,因此添加了该报表作为正确性检查。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Note the postcondition indicating the association of a new receivable entry in accounts receivable. Although this responsibility is outside the bounds of the NextGen system, the accounts receivable system is within the control of the business, so the statement has been added as a correctness check.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,在测试期间,从这个后置条件可以清楚地看出,应该测试应收账款系统是否存在新的应收账款分录。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, during testing it is clear from this post-condition that the accounts receivable system should be tested for the presence of a new receivable entry.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            签订 CO6 合同:makeCheckPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            操作:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Operation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            makeCheckPayment( driversLicenceNumber )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            makeCheckPayment( driversLicenceNumber )

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            交叉引用:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Cross References:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用案例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use Cases: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            前提 条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Preconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            正在进行中的销售,所有物品都已输入。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            An underway sale exists and all items have been entered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            后置条件:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Postconditions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 创建了 CheckPayment pmt

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a CheckPayment pmt was created

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt 与当前的 Sale 销售相关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt was associated with the current Sale sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 创建了 DriversLicense dl;dl.number = driversLicenseNumber

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a DriversLicense dl was created; dl.number = driversLicenseNumber

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - DL 与 PMT 相关

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - dl was associated with pmt

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 已创建 CheckPaymentRequest cpr。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - a CheckPaymentRequest cpr was created.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - PMT 与 CPR 相关

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - pmt was associated with cpr

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - 促销作为已完成的销售与品牌旗舰店相关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            - sale was associated with the Store as a completed sale



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              第 32 章.域模型优化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Chapter 32. Domain Model Refinement

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              粗暴的分类和错误的概括是有组织生活的诅咒。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              H.G. Wells 的概括

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Crude classifications and false generalizations are the curse of the organized life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A generalization by H.G. Wells

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 使用泛化、特化、关联类、时间间隔、组合和包来优化域模型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Refine the domain model with generalizations, specializations, association classes, time intervals, composition, and packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 确定何时值得显示子类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Identify when showing a subclass is worthwhile.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                泛化和专业化是领域建模中支持表达经济性的基本概念;此外,概念类层次结构通常是利用继承和减少代码重复的软件类层次结构的灵感基础。关联类捕获有关关联本身的信息。时间间隔捕获了某些业务对象在有限时间内有效的重要概念。包是一种将大型域模型组织成较小单元的方法。这些概念中的大多数都是在 NextGen 案例研究的上下文中引入的;从第 538 页开始显示了一个改进的 Monopoly 域模型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Generalization and specialization are fundamental concepts in domain modeling that support an economy of expression; further, conceptual class hierarchies are often the basis of inspiration for software class hierarchies that exploit inheritance and reduce duplication of code. Association classes capture information about an association itself. Time intervals capture the important concept that some business objects are valid for a limited time. And packages are a way to organize large domain models into smaller units. Most of these concepts are introduced in the context of the NextGen case study; a refined Monopoly domain model is shown starting on p. 538.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.1. NextGen 域模型的新概念

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.1. New Concepts for the NextGen Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  与迭代 1 一样,可以通过考虑此迭代需求中的概念来增量开发域模型。概念类别列表和名词短语识别等技术会有所帮助。开发健壮而丰富的领域模型的一种有效方法是研究其他作者关于该主题的工作,例如 [Fowler96]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As in iteration-1, the Domain Model may be incrementally developed by considering the concepts in the requirements for this iteration. Techniques such as the Concept Category List and noun phrase identification will help. An effective approach to developing a robust and rich domain model is to study the work of other authors on this subject, such as [Fowler96].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  概念画板类别列表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Concepts Category List

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Table 32.1 显示了此迭代中正在考虑的一些值得注意的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Table 32.1 shows some noteworthy concepts being considered in this iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  表 32.1.类别概念列表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  类别

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Category

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  例子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Examples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  物理或有形对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  physical or tangible objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  信用卡, 支票

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CreditCard, Check

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  交易

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Transactions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CashPayment、CreditPayment、CheckPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CashPayment, CreditPayment, CheckPayment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  我们系统外部的其他计算机或机电系统

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  other computer or electro-mechanical systems external to our system

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CreditAuthorizationService、CheckAuthorizationService

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CreditAuthorizationService, CheckAuthorizationService

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  抽象名词概念

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  abstract noun concepts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  组织

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  organizations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CreditAuthorizationService、CheckAuthorizationService

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  CreditAuthorizationService, CheckAuthorizationService

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  财务、工作、合同、法律事务的记录

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  records of finance, work, contracts, legal matters

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  应收账款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  AccountsReceivable



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  用例中的名词短语识别

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Noun Phrase Identification from the Use Cases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  重申一下,名词短语识别不能机械地应用于识别要包含在域模型中的相关概念。必须进行判断并开发适当的抽象,因为自然语言是模棱两可的,相关概念在现有文本中并不总是明确或清晰的。但是,它是域建模中的一种实用技术,因为它很简单。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To reiterate, noun phrase identification cannot be mechanically applied to identify relevant concepts to include in the domain model. Judgement must be applied and suitable abstractions developed, since natural language is ambiguous and relevant concepts are not always explicit or clear in existing text. However, it is a practical technique in domain modeling since it is straightforward.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此迭代处理贷记和支票付款的 Process Sale 使用案例的场景。下面显示了这些扩展的一些名词短语标识:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This iteration handles the scenarios of the Process Sale use case for credit and check payments. The following shows some noun phrase identification from these extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  用例 UC1:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  扩展:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Extensions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7b.通过信用卡支付:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 客户输入其信用账户信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. 系统向外部 Payment Authorization Service System 发送支付授权请求,并请求支付审批

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2a.系统检测到与外部系统协作失败:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. 系统向收银员发出错误信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. 收银员要求客户进行替代付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 系统收到付款批准并向出纳发出批准信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    3a.系统收到付款被拒

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. 系统向收银员发出拒绝信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. 收银员要求客户进行替代付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. 系统记录贷方付款,其中包括付款审批。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 系统提供信用支付签名输入机制。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. 收银员要求 Customer 提供信用付款签名。客户输入签名。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7c.支票支付:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. 客户写一张支票,并将其和他们的驾驶执照交给出纳。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. 出纳在支票上写下驾照号码,输入该号码,然后请求支票付款授权

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. 生成支票付款请求并将其发送到外部支票授权服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. 收到支票付款批准,并向出纳发出批准信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. 系统记录支票付款,其中包括付款审批。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7b. Paying by credit:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. Customer enters their credit account information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. System sends payment authorization request to an external Payment Authorization Service System, and requests payment approval.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2a. System detects failure to collaborate with external system:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. System signals error to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. Cashier asks Customer for alternate payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. System receives payment approval and signals approval to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    3a. System receives payment denial:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. System signals denial to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. Cashier asks Customer for alternate payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. System records the credit payment, which includes the payment approval.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. System presents credit payment signature input mechanism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  6. Cashier asks Customer for a credit payment signature. Customer enters signature.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  7c. Paying by check:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. The Customer writes a check, and gives it and their driver's license to the Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Cashier writes the driver's license number on the check, enters it, and requests check payment authorization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. Generates a check payment request and sends it to an external Check Authorization Service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4. Receives a check payment approval and signals approval to Cashier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  5. System records the check payment, which includes the payment approval.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  授权服务事务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Authorization Service Transactions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  名词短语标识揭示了 CreditPaymentRequestCreditApprovalReply 等概念。这些实际上可以被视为与外部服务的交易类型,一般来说,识别此类交易很有用,因为活动和流程往往围绕它们展开。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The noun phrase identification reveals concepts such as CreditPaymentRequest and CreditApprovalReply. These may in fact be viewed as types of transactions with external services, and in general, it is useful to identify such transactions because activities and processes tend to revolve around them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这些交易不必表示计算机记录或跨行传输的比特。它们表示独立于其执行方式的事务的抽象。例如,信用付款请求可能由人们通过电话交谈、两台计算机相互发送记录或消息等来执行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  These transactions do not have to represent computer records or bits travelling over a line. They represent the abstraction of the transaction independent of its means of execution. For example, a credit payment request may be executed by people talking on the phone, by two computers sending records or messages to each other, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.2. 泛化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.2. Generalization

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    CashPayment、CreditPaymentCheckPayment 的概念都非常相似。在这种情况下,可以(并且有用[1])将它们组织成一个泛化-专业化类层次结构(或简称类层次结构),其中超类 Payment 代表一个更通用的概念,而子类代表更专业的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The concepts CashPayment, CreditPayment, and CheckPayment are all very similar. In this situation, it is possible (and useful[1]) to organize them (as in Figure 32.1) into a generalization-specialization class hierarchy (or simply class hierarchy) in which the superclass Payment represents a more general concept, and the subclasses more specialized ones.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] 在本章的后面,我们将研究定义类层次结构的原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] Later in the chapter, we will investigate reasons to define class hierarchies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.1.泛化 - 专业化层次结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,本章中对类的讨论是指概念类,而不是软件类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note that the discussion of classes in this chapter refers to conceptual classes, not software classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    泛化是识别概念之间的共性并定义超类(一般概念)和子类(专业概念)关系的活动。这是一种在概念之间构建分类的方法,然后在类层次结构中进行说明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Generalization is the activity of identifying commonality among concepts and defining superclass (general concept) and subclass (specialized concept) relationships. It is a way to construct taxonomic classifications among concepts which are then illustrated in class hierarchies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    识别超类和子类在域模型中很有价值,因为它们的存在使我们能够以更一般、更精细和更抽象的术语来理解概念。它导致表达经济、理解力提高和重复信息减少。尽管我们现在关注的是 UP 领域模型而不是软件设计模型,但后来将 super- 和 subclass 作为使用继承的软件类的设计和实现会产生更好的软件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Identifying a superclass and subclasses is of value in a domain model because their presence allows us to understand concepts in more general, refined and abstract terms. It leads to economy of expression, improved comprehension and a reduction in repeated information. And although we are focusing now on the UP Domain Model and not the software Design Model, the later design and implementation of super- and subclass as software classes that use inheritance yields better software.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因此:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Thus:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    确定与当前迭代相关的域超类和子类,并在 Domain Model 中说明它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Identify domain superclasses and subclasses relevant to the current iteration, and illustrate them in the Domain Model.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    UML回顾一下上一章中介绍的泛化表示法,在 UML 中,元素之间的泛化关系用一个大的空心三角形表示,该三角形指向更通用的元素和更专业的元素(参见图 32.2)。可以使用单独的目标或共享目标箭头样式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    UML To review the generalization notation introduced in a prior chapter, in the UML the generalization relationship between elements is indicated with a large hollow triangle pointing to the more general element from the more specialized one (see Figure 32.2). Either a separate target or shared target arrow style may be used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.2.具有单独和共享箭头表示法的类层次结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.3. 定义概念超类和子类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.3. Defining Conceptual Superclasses and Subclasses

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      由于识别概念上的超类和子类很有价值,因此根据类定义和类集清晰准确地理解泛化、超类和子类是有用的。[2] 以下各节将探讨这些内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Since it is valuable to identify conceptual super- and subclasses, it is useful to clearly and precisely understand generalization, superclasses, and subclasses in terms of class definition and class sets.[2] This following sections explore these.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [2] 也就是说,类的内涵和外延。这次讨论的灵感来自 [MO95]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [2] That is, a class's intension and extension. This discussion was inspired by [MO95].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      泛化和概念类定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Generalization and Conceptual Class Definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念超类与子类的关系是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What is the relationship of a conceptual superclass to a subclass?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念超类定义比子类定义更通用或更全面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A conceptual superclass definition is more general or encompassing than a subclass definition.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,考虑超类 Payment 及其子类 (CashPayment 等)。假设 Payment 的定义是它代表将购买资金(不一定是现金)从一方转移到另一方的交易,并且所有付款都有一定数量的转账。与此相对应的模型如图 32.3 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, consider the superclass Payment and its subclasses (CashPayment, and so on). Assume the definition of Payment is that it represents the transaction of transferring money (not necessarily cash) for a purchase from one party to another, and that all payments have an amount of money transferred. The model corresponding to this is shown in Figure 32.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.3.付款类层次结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CreditPayment 是通过信贷机构进行的资金转账,需要获得授权。我对 Payment 的定义包含并且比我对 CreditPayment 的定义更普遍。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A CreditPayment is a transfer of money via a credit institution which needs to be authorized. My definition of Payment encompasses and is more general than my definition of CreditPayment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      泛化和类集

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Generalization and Class Sets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念子类和超类在集合成员资格方面是相关的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Conceptual subclasses and superclasses are related in terms of set membership.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念子类集的所有成员都是其超类集的成员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      All members of a conceptual subclass set are members of their superclass set.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,就集合成员资格而言,集合 CreditPayment 的所有实例也是集合 Payment 的成员。在维恩图中,如图 32.4 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, in terms of set membership, all instances of the set CreditPayment are also members of the set Payment. In a Venn diagram, this is shown as in Figure 32.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.4.集合关系的维恩图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念子类定义一致性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Conceptual Subclass Definition Conformance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      创建类层次结构时,将对适用于子类的超类进行陈述。例如,图 32.5 指出所有 Payments 都有一个金额并与 Sale 相关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When a class hierarchy is created, statements about superclasses that apply to subclasses are made. For example, Figure 32.5 states that all Payments have an amount and are associated with a Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.5.子类一致性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      所有 Payment 子类都必须符合拥有金额并支付 Sale 的要求。通常,符合超类定义的规则是 100% 规则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      All Payment subclasses must conform to having an amount and paying for a Sale. In general, this rule of conformance to a superclass definition is the 100% Rule:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指南:100% 规则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: 100% Rule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念超类的定义 100% 应适用于子类。子类必须 100% 符合超类的:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      100% of the conceptual superclass's definition should be applicable to the subclass. The subclass must conform to 100% of the superclass's:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • attributes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 协会

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • associations



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念子类集一致性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Conceptual Subclass Set Conformance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      概念子类应该是超类集合的成员。因此,CreditPayment 应该是 Payments 集的成员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A conceptual subclass should be a member of the set of the superclass. Thus, CreditPayment should be a member of the set of Payments.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      非正式地,这表达了概念子类是一种超类的概念。CreditPayment 是一种 Payment。更简洁地说,is-a-kind-of 称为 is-a

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Informally, this expresses the notion that the conceptual subclass is a kind of superclass. CreditPayment is a kind of Payment. More tersely, is-a-kind-of is called is-a.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这种一致性就是 Is-a 规则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This kind of conformance is the Is-a Rule:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指南:Is-a 规则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: Is-a Rule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      子类集的所有成员都必须是其超类集的成员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      All the members of a subclass set must be members of their superclass set.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在自然语言中,这通常可以通过形成以下语句来非正式地测试:Subclass 是一个 Superclass。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In natural language, this can usually be informally tested by forming the statement: Subclass is a Superclass.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,语句 CreditPayment is a Payment 是有意义的,并且传达了集合成员资格一致性的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For instance, the statement CreditPayment is a Payment makes sense, and conveys the notion of set membership conformance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      什么是正确的概念子类?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What Is a Correct Conceptual Subclass?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      从上面的讨论中,应用以下测试[3] 在构建域模型时定义正确的子类:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      From the above discussion, apply the following tests[3] to define a correct subclass when constructing a domain model:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [3] 选择这些规则名称是因为它们的助记符支持而不是精度。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [3] These rule names have been chosen for their mnemonic support rather than precision.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      潜在的子类应符合:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A potential subclass should conform to the:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 100% 规则(定义一致性)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 100% Rule (definition conformance)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Is-a 规则(设置成员资格一致性)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Is-a Rule (set membership conformance)



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        32.4. 何时定义概念子类?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        32.4. When to Define a Conceptual Subclass?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        已检查确保子类正确的规则(Is-a 和 100% 规则)。但是,我们什么时候应该费心定义一个子类呢?首先,定义:概念类划分是将概念类划分为不相交的子类(或 Odell 术语中的类型)[MO95]。这个问题可以重述为:“什么时候显示概念类划分是有用的?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Rules to ensure that a subclass is correct have been examined (the Is-a and 100% rules). However, when should we even bother to define a subclass? First, a definition: A conceptual class partition is a division of a conceptual class into disjoint subclasses (or types in Odell's terminology) [MO95]. The question may be restated as: "When is it useful to show a conceptual class partition?"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例如,在 POS 域中,Customer 可以正确分区(或子类化)为 MaleCustomerFemaleCustomer。但是在我们的模型中显示这一点是否相关或有用(参见图 32.6)?这个分区对我们的域没有用;下一节将解释原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For example, in the POS domain, Customer may be correctly partitioned (or subclassed) into MaleCustomer and FemaleCustomer. But is it relevant or useful to show this in our model (see Figure 32.6)? This partition is not useful for our domain; the next section explains why.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 32.6.法律概念类划分,但它在我们的领域有用吗?



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        将概念类划分为子类的动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Motivations to Partition a Conceptual Class into Subclasses

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        以下是将类划分为子类的强烈动机:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The following are strong motivations to partition a class into subclasses:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在以下情况下创建超类的概念子类:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Create a conceptual subclass of a superclass when:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 该子类具有其他感兴趣的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. The subclass has additional attributes of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 该子类具有其他相关关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. The subclass has additional associations of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        5. 子类概念的操作、处理、反应或操作方式与超类或其他子类不同,其方式令人感兴趣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        6. The subclass concept is operated on, handled, reacted to, or manipulated differently than the superclass or other subclasses, in ways that are of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        7. 子类概念表示一个有生命的事物(例如,动物、机器人),其行为与超类或其他子类不同,但方式令人感兴趣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        8. The subclass concept represents an animate thing (for example, animal, robot) that behaves differently than the superclass or other subclasses, in ways that are of interest.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        根据上述标准,将 Customer 划分为子类 MaleCustomerFemaleCustomer 并不具有说服力,因为它们没有额外的属性或关联,没有以不同的方式操作(处理),并且不会以有趣的方式表现出不同的行为[4]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Based on the above criteria, it is not compelling to partition Customer into the subclasses MaleCustomer and FemaleCustomer because they have no additional attributes or associations, are not operated on (treated) differently, and do not behave differently in ways that are of interest[4].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [4] 男性和女性的购物习惯确实不同。但是,这些与我们当前的用例要求无关,该要求是我们调查的标准。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [4] Men and women do exhibit different shopping habits. However, these are not relevant to our current use case requirementsthe criterion that bounds our investigation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Table 32.2 显示了使用这些标准从 payments 领域和其他领域划分 Class Partition 的一些示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Table 32.2 shows some examples of class partitions from the domain of payments and other areas, using these criteria.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        表 32.2.示例子类分区。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念子类动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Conceptual Subclass Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例子

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Examples

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        该子类具有其他感兴趣的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The subclass has additional attributes of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        付款不适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Payments not applicable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图书馆Book 是 LoanableResource 的子类,具有 ISBN 属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Library Book, subclass of LoanableResource, has an ISBN attribute.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        该子类具有其他相关关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The subclass has additional associations of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        付款CreditPayment 是 Payment 的子类,与 CreditCard 相关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Payments CreditPayment, subclass of Payment, is associated with a CreditCard.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图书馆Video 是 LoanableResource 的子类,与 Director 关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Library Video, subclass of LoanableResource, is associated with Director.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        子类概念的操作、处理、反应或操作方式与超类或其他子类不同,以有趣的方式进行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The subclass concept is operated upon, handled, reacted to, or manipulated differently than the superclass or other subclasses, in ways that are of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        付款CreditPayment 是 Payment 的子类,其授权方式与其他类型的付款不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Payments CreditPayment, subclass of Payment, is handled differently than other kinds of payments in how it is authorized.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图书馆软件是 LoanableResource 的子类,在借出之前需要押金。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Library Software, subclass of LoanableResource, requires a deposit before it may be loaned.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        子类概念表示一个有生命的事物(例如,动物、机器人),其行为与超类或其他子类不同,但方式令人感兴趣。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The subclass concept represents an animate thing (for example, animal, robot) that behaves differently than the superclass or other subclasses, in ways that are of interest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        付款不适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Payments not applicable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        不适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Library not applicable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        市场调查MaleHuman 是 Human 的子类,在购物习惯方面与 FemaleHuman 的行为不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Market Research MaleHuman, subclass of Human, behaves differently than FemaleHuman with respect to shopping habits.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          32.5. 何时定义概念超类?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          32.5. When to Define a Conceptual Superclass?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当在潜在子类中确定共性时,通常建议泛化为公共超类。以下是泛化和定义超类的动机:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Generalization into a common superclass is usually advised when commonality is identified among potential subclasses. The following are motivations to generalize and define a superclass:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在以下情况下,在与子类的泛化关系中创建超类:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Create a superclass in a generalization relationship to subclasses when:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 潜在的概念子类代表了类似概念的变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The potential conceptual subclasses represent variations of a similar concept.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 子类将符合 100% 和 Is-a 规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The subclasses will conform to the 100% and Is-a rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 所有子类都具有相同的属性,该属性可以分解出来并在 superclass 中表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • All subclasses have the same attribute that can be factored out and expressed in the superclass.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 所有子类都具有相同的关联,这些关联可以被分解出来并与超类相关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • All subclasses have the same association that can be factored out and related to the superclass.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          以下部分说明了这些要点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The following sections illustrate these points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            32.6. NextGen POS 概念类层次结构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            32.6. NextGen POS Conceptual Class Hierarchies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            付款类别

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Payment Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            根据上述划分 Payment 类的标准,创建各种付款的类层次结构非常有用。超类和子类的理由如图 32.7 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Based on the above criteria for partitioning the Payment class, it is useful to create a class hierarchy of various kinds of payments. The justification for the superclass and subclasses is shown in Figure 32.7.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.7.证明 Payment 子类的合理性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            授权服务类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Authorization Service Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            信用和支票授权服务是类似概念的变体,具有共同的兴趣属性。这导致了图 32.8 中的类层次结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Credit and check authorization services are variations on a similar concept, and have common attributes of interest. This leads to the class hierarchy in Figure 32.8.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.8.证明 AuthorizationService 层次结构的合理性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            授权事务类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Authorization Transaction Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            对各种授权服务事务(请求和回复)进行建模是一个有趣的案例。通常,具有外部服务的事务在域模型中显示很有用,因为活动和流程往往围绕它们展开。它们是重要的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Modeling the various kinds of authorization service transactions (requests and replies) presents an interesting case. In general, transactions with external services are useful to show in a domain model because activities and processes tend to revolve around them. They are important concepts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            建模者是否应该说明外部服务事务的每种变体?这要看情况。如前所述,域模型不一定正确或错误,而是或多或少有用。它们很有用,因为每个事务类都与不同的概念、流程和业务规则相关。[5]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Should the modeler illustrate every variation of an external service transaction? It depends. As mentioned, domain models are not necessarily correct or wrong, but rather more or less useful. They are useful, because each transaction class is related to different concepts, processes, and business rules.[5]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [5] 在电信领域模型中,识别每种交换或交换消息同样有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [5] In telecommunications domain models, it is similarly useful to identify each kind of exchange or switch message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            第二个有趣的问题是在模型中显示有用的泛化程度。为了便于讨论,让我们假设每个交易都有一个日期和时间。这些通用属性,再加上为这一系列相关概念创建最终泛化的愿望,证明了创建 PaymentAuthorizationTransaction 的合理性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A second interesting question is the degree of generalization that is useful to show in the model. For argument's sake, let us assume that every transaction has a date and time. These common attributes, plus the desire to create an ultimate generalization for this family of related concepts, justifies the creation of PaymentAuthorizationTransaction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            但是,如图 32.9 所示,将回复泛化为 CreditPaymentAuthorizationReplyCheckPaymentAuthorizationReply 是否有用,或者如图 32.10 所示,显示较少的泛化就足够了?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            But is it useful to generalize a reply into a CreditPaymentAuthorizationReply and CheckPaymentAuthorizationReply, as shown in Figure 32.9, or is it sufficient to show less generalization, as depicted in Figure 32.10?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.9.外部服务事务的一种可能的类层次结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.10.备用事务类层次结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.10 中所示的类层次结构在泛化方面足够有用,因为额外的泛化不会增加明显的价值。图 32.9 的层次结构表达了更精细的泛化粒度,它不会显著增强我们对概念和业务规则的理解,但它确实使模型更加复杂,除非它带来其他好处,否则增加复杂性是不可取的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The class hierarchy shown in Figure 32.10 is sufficiently useful in terms of generalization, because the additional generalizations do not add obvious value. The hierarchy of Figure 32.9 expresses a finer granularity of generalization that does not significantly enhance our understanding of the concepts and business rules, but it does make the model more complexand added complexity is undesirable unless it confers other benefits.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              32.7. 抽象概念类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              32.7. Abstract Conceptual Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在域模型中识别抽象类很有用,因为它们限制了可以具有具体实例的类,从而阐明了问题域的规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It is useful to identify abstract classes in the domain model because they constrain what classes it is possible to have concrete instances of, thus clarifying the rules of the problem domain.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如果类 C 的每个成员也必须是子类的成员,则类 C 称为抽象概念类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              If every member of a class C must also be a member of a subclass, then class C is called an abstract conceptual class.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,假设每个 Payment 实例必须更具体地是子类 CreditPayment、CashPaymentCheckPayment 的实例。这在图 32.11 (b) 的维恩图中得到了说明。由于每个 Payment 成员也是子类的成员,因此 Payment 根据定义是一个抽象的概念类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, assume that every Payment instance must more specifically be an instance of the subclass CreditPayment, CashPayment, or CheckPayment. This is illustrated in the Venn diagram of Figure 32.11 (b). Since every Payment member is also a member of a subclass, Payment is an abstract conceptual class by definition.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 32.11.抽象概念类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              相反,如果可以有不是子类成员的 Payment 实例,则它不是抽象类,如图 32.11 (a) 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              By contrast, if there can be Payment instances that are not members of a subclass, it is not an abstract class, as illustrated in Figure 32.11 (a).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在 POS 域中,每个 Payment 实际上都是子类的成员。图 32.11 (b) 是对付款的正确描述;因此,Payment 是一个抽象的概念类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In the POS domain, every Payment is really a member of a subclass. Figure 32.11 (b) is the correct depiction of payments; therefore, Payment is an abstract conceptual class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 中的抽象类表示法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Abstract Class Notation in the UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              回顾一下,UML 提供了一个表示法来表示抽象类类类的斜体(参见图 32.12)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              To review, the UML provides a notation to indicate abstract classesthe class name is italicized (see Figure 32.12).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 32.12.抽象类表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              标识抽象类,并在域模型中用斜体名称说明它们,或使用 {abstract} 关键字。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Identify abstract classes and illustrate them with an italicized name in the Domain Model, or use the {abstract} keyword.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                32.8. 对变化的状态进行建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                32.8. Modeling Changing States

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                假设付款可以处于 Unauthorized 或 Authorized 状态,并且在 domain model 中显示这一点是有意义的(可能不是真的,但为了讨论而假设如此)。如图 32.13 所示,一种建模方法是定义 Payment 的子类: UnauthorizedPaymentAuthorizedPayment 。但是,请注意,付款不会停留在这些状态之一;它通常从 Unauthorized 转换为 Authorized。这导致了以下准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Assume that a payment can either be in an unauthorized or authorized state, and it is meaningful to show this in the domain model (it may not really be, but assume so for the discussion). As shown in Figure 32.13, one modeling approach is to define subclasses of Payment: UnauthorizedPayment and AuthorizedPayment. However, note that a payment does not stay in one of these states; it typically transitions from unauthorized to authorized. This leads to the following guideline:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 32.13.对不断变化的状态进行建模。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                不要将概念 X 的状态建模为 X 的子类,而是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do not model the states of a concept X as subclasses of X. Rather, either:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 定义状态层次结构并将状态与 X 关联,或者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Define a state hierarchy and associate the states with X, or

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 忽略在域模型中显示概念的状态;而是在 State Diagrams 中显示状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Ignore showing the states of a concept in the domain model; show the states in state diagrams instead.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.9. 软件中的类层次结构和继承

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.9. Class Hierarchies and Inheritance in Software

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这个关于概念类层次结构的讨论没有提到继承,因为讨论的重点是域模型概念视角,而不是软件对象。在面向对象的语言中,软件子类通过创建软件类层次结构继承其超类的属性和操作定义。继承是一种软件机制,用于使超类事物适用于子类。它支持从子类重构代码并将其推送到类层次结构中。因此,继承在领域模型的讨论中没有真正的作用,尽管当我们过渡到设计和实现视图时,它肯定会发挥作用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This discussion of conceptual class hierarchies has not mentioned inheritance, because the discussion is focused on a domain model conceptual perspective, not software objects. In an object-oriented language, a software subclass inherits the attribute and operation definitions of its superclasses by the creation of software class hierarchies. Inheritance is a software mechanism to make superclass things applicable to subclasses. It supports refactoring code from subclasses and pushing it up class hierarchies. Therefore, inheritance has no real part to play in the discussion of the domain model, although it most definitely does when we transition to the design and implementation view.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  此处生成的概念类层次结构可能会也可能不会反映在设计模型中。例如,授权服务事务类的层次结构可以折叠或扩展为备用软件类层次结构,具体取决于语言功能和其他因素。例如,C++ 模板化类有时可以减少类的数量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The conceptual class hierarchies generated here may or may not be reflected in the Design Model. For example, the hierarchy of authorization service transaction classes may be collapsed or expanded into alternate software class hierarchies, depending on language features and other factors. For instance, C++ templatized classes can sometimes reduce the number of classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.10. 关联类

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.10. Association Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    以下域要求为关联类奠定了基础:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The following domain requirements set the stage for association classes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 授权服务为每个商店分配一个商家 ID,以便在通信期间进行识别。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Authorization services assign a merchant ID to each store for identification during communications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 从商店到授权服务的付款授权请求需要向服务标识商店的商家 ID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • A payment authorization request from the store to an authorization service needs the merchant ID that identifies the store to the service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 此外,商店的每项服务都有不同的商家 ID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Furthermore, a store has a different merchant ID for each service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    商户 ID 属性应位于 UP 域模型中的哪个位置?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Where in the UP Domain Model should the merchant ID attribute reside?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    merchantID 放在 Store 中是不正确的,因为 Store 可以有多个 merchantID 值。将其放置在 AuthorizationService 中也是如此(参见图 32.14)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Placing merchantID in Store is incorrect because a Store can have more than one value for merchantID. The same is true with placing it in AuthorizationService (see Figure 32.14).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.14.属性使用不当。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这导致了以下建模原则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This leads to the following modeling principle:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在域模型中,如果类 C 可以同时具有同一类型的属性 A 的多个值,则不要将属性 A 放在 C 中。将属性 A 放在与 C 关联的另一个类中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In a domain model, if a class C can simultaneously have many values for the same kind of attribute A, do not place attribute A in C. Place attribute A in another class that is associated with C.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 一个人可能有多个电话号码。将电话号码放在另一个类中,例如 PhoneNumber 或 ContactInformation,并将其中许多类与 Person 相关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • A Person may have many phone numbers. Place phone number in another class, such as PhoneNumber or ContactInformation, and associate many of these to Person.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    上述原则表明,像图 32.15 中的模型这样的东西更合适。在商业世界中,什么概念正式记录了服务向客户提供的服务相关的信息?合同帐户

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The above principle suggests that something like the model in Figure 32.15 is more appropriate. In the business world, what concept formally records the information related to the services that a service provides to a customer?A Contract or Account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.15.首次尝试对 merchantID 问题进行建模。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    StoreAuthorizationService 都与 ServiceContract 相关这一事实表明,它依赖于两者之间的关系。可以将 merchantID 视为与 StoreAuthorizationService 之间的关联相关的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The fact that both Store and AuthorizationService are related to ServiceContract is a clue that it is dependent on the relationship between the two. The merchantID may be thought of as an attribute related to the association between Store and AuthorizationService.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这导致了关联类的概念,在其中我们可以向关联本身添加功能。ServiceContract 可以建模为与 StoreAuthorizationService 之间的关联相关的关联类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This leads to the notion of an association class, in which we can add features to the association itself. ServiceContract may be modeled as an association class related to the association between Store and AuthorizationService.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在 UML 中,这用从关联到关联类的虚线来表示。图 32.16 直观地传达了 ServiceContract 及其属性与 StoreAuthorizationService 之间的关联相关,并且 ServiceContract 的生命周期取决于关系的想法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In the UML, this is illustrated with a dashed line from the association to the association class. Figure 32.16 visually communicates the idea that a ServiceContract and its attributes are related to the association between a Store and AuthorizationService, and that the lifetime of the ServiceContract is dependent on the relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.16.关联类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    添加关联类的准则包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guidelines for adding association classes include the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    关联类在域模型中可能有用的线索:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Clues that an association class might be useful in a domain model:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 属性与关联相关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • An attribute is related to an association.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • association 类的实例对关联具有生命周期依赖关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Instances of the association class have a lifetime dependency on the association.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 两个概念与关联本身相关的信息之间存在多对多关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • There is a many-to-many association between two concepts and information associated with the association itself.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    多对多关联的存在是一个常见的线索,表明有用的关联类正潜伏在后台的某个地方;当您看到一个 Association 类时,请考虑一个 Association 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The presence of a many-to-many association is a common clue that a useful association class is lurking in the background somewhere; when you see one, consider an association class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.17 说明了关联类的其他一些示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Figure 32.17 illustrates some other examples of association classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.17.Association 类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.11. 聚合和组合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.11. Aggregation and Composition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这前几段重复了第 264 页的引言。聚合是 UML 中一种模糊的关联,它松散地表示整体部分关系(就像许多普通关联一样)。与 UML 相比,它在 UML 中没有有意义的独特语义,但该术语在 UML 中定义。为什么?引用 Rumbaugh(UML 的最初和关键创建者之一)的话:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      These first few paragraphs repeat the introduction on p. 264. Aggregation is a vague kind of association in the UML that loosely suggests whole-part relationships (as do many ordinary associations). It has no meaningful distinct semantics in the UML versus a plain association, but the term is defined in the UML. Why? To quote Rumbaugh (one of the original and key UML creators):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      尽管聚合附带的语义很少,但每个人都认为这是必要的(出于不同的原因)。将其视为建模安慰剂。[RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In spite of the few semantics attached to aggregation, everybody thinks it is necessary (for different reasons). Think of it as a modeling placebo. [RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指南: 因此,遵循 UML 创建者的建议,不要费心在 UML 中使用聚合;相反,在适当的时候使用组合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: Therefore, following the advice of UML creators, don't bother to use aggregation in the UML; rather, use composition when appropriate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      组合(也称为复合聚合)是一种强大的全部分聚合,可用于在某些模型中显示。组合关系意味着 1) 部件的实例(例如 Square)一次只属于一个复合实例(例如一个 Board),2) 该部件必须始终属于一个复合部件(没有自由浮动的 Fingers),以及 3) 复合部件负责创建和删除其部件本身创建/删除部件, 或通过与其他对象协作。与此约束相关的是,如果合成被销毁,则必须销毁其部分,或附加到另一个复合合成不允许自由浮动的手指!例如,如果一个实体纸质大富翁游戏板被摧毁,我们认为方块也被摧毁了(概念角度)。同样,在 DCD 软件的角度来看,如果一个软件 Board 对象被销毁,则其软件 Square 对象也会被销毁。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Composition, also known as composite aggregation, is a strong kind of whole-part aggregation and is useful to show in some models. A composition relationship implies that 1) an instance of the part (such as a Square) belongs to only one composite instance (such as one Board) at a time, 2) the part must always belong to a composite (no free-floating Fingers), and 3) the composite is responsible for the creation and deletion of its partseither by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must either be destroyed, or attached to another compositeno free-floating Fingers allowed! For example, if a physical paper Monopoly game board is destroyed, we think of the squares as being destroyed as well (a conceptual perspective). Likewise, if a software Board object is destroyed, its software Square objects are destroyed, in a DCD software perspective.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如何识别合成

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How to Identify Composition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在某些情况下,组合物的存在是显而易见的通常在物理组件中。但有时,情况并不清楚。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In some cases, the presence of composition is obvioususually in physical assemblies. But sometimes, it is not clear.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      关于构图:如有疑问,请省略。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      On composition: If in doubt, leave it out.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      以下是一些建议何时显示聚合的准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Here are some guidelines that suggest when to show aggregation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在以下情况下,请考虑显示合成:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Consider showing composition when:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 部件的生命周期受 composite 生命周期的约束,因此部件对整体存在创建-删除依赖关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The lifetime of the part is bound within the lifetime of the compositethere is a create-delete dependency of the part on the whole.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 有一个明显的整体部分物理或逻辑集合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • There is an obvious whole-part physical or logical assembly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 组合的某些属性会传播到零件,例如位置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Some properties of the composite propagate to the parts, such as the location.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 应用于复合的操作会传播到零件,例如销毁、移动、录制。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Operations applied to the composite propagate to the parts, such as destruction, movement, recording.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      显示合成的好处

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A Benefit of Showing Composition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      识别和说明构图并不重要;将其从 Domain Model 中排除是相当合理的。大多数(如果不是全部)经验丰富的领域建模者都看到,浪费在争论这些关联的细节上的非生产性时间。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Identifying and illustrating composition is not profoundly important; it is quite reasonable to exclude it from a domain model. Mostif not allexperienced domain modelers have seen unproductive time wasted debating the fine points of these associations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      发现并显示组合,因为它具有以下好处,其中大部分与设计有关,而不是与分析有关,这就是为什么将其从域模型中排除不是很重要的原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Discover and show composition because it has the following benefits, most of which relate to the design rather than the analysis, which is why its exclusion from the domain model is not very significant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 它阐明了关于独立于整体的零件的合格存在的域约束。在复合聚合中,该部分可能不存在于整体的生命周期之外。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 在设计工作期间,这会影响整个和部分软件类和数据库元素之间的创建-删除依赖关系(在引用完整性和级联删除路径方面)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • It clarifies the domain constraints regarding the eligible existence of the part independent of the whole. In composite aggregation, the part may not exist outside of the lifetime of the whole.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • During design work, this has an impact on the create-delete dependencies between the whole and part software classes and database elements (in terms of referential integrity and cascading delete paths).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 它有助于使用 GRASP Creator 模式识别创建者(复合)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • It assists in the identification of a creator (the composite) using the GRASP Creator pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 应用于整体的操作 copy 和 delete 通常会传播到部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Operationssuch as copy and deleteapplied to the whole often propagate to the parts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      NextGen 域模型中的组合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Composition in the NextGen Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 POS 域中,SalesLineItems 可被视为复合 Sale 的一部分;通常,Transaction line items 被视为 aggregate transaction 的一部分(参见图 32.18)。除了符合该模式之外,Sale上的行项目还存在创建-删除依赖关系:它们的生命周期受 Sale 生命周期的约束。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In the POS domain, the SalesLineItems may be considered a part of a composite Sale; in general, transaction line items are viewed as parts of an aggregate transaction (see Figure 32.18). In addition to conformance to that pattern, there is a create-delete dependency of the line items on the Saletheir lifetime is bound within the lifetime of the Sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.18.销售点应用程序中的聚合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      出于类似的理由,ProductCatalogProductDescriptions 的组合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      By similar justification, ProductCatalog is a composite of ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      没有其他关系是令人信服的组合,它暗示了整体部分语义、创建-删除依赖关系以及“如有疑问,请将其排除在外”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      No other relationship is a compelling combination that suggests whole-part semantics, a create-delete dependency, and "If in doubt, leave it out."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        32.12. 时间间隔和产品价格修复迭代 1 “错误”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        32.12. Time Intervals and Product PricesFixing an Iteration 1 "Error"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在第一次迭代中,SalesLineItemsProductDescriptions 相关联,后者记录了项目的价格。对于早期迭代来说,这是一个合理的简化,但需要修改。它提出了一个有趣且广泛适用的问题,即与信息、合同等相关的时间间隔

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the first iteration, SalesLineItems were associated with ProductDescriptions, that recorded the price of an item. This was a reasonable simplification for early iterations, but needs to be amended. It raises the interestingand widely applicableissue of time intervals associated with information, contracts, and the like.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如果 SalesLineItem 始终检索 ProductDescriptions 中记录的当前价格,那么当对象中的价格发生更改时,旧销售额将引用新价格,这是不正确的。需要区分销售时的历史价格和当前价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        If a SalesLineItem always retrieved the current price recorded in a ProductDescriptions, then when the price was changed in the object, old sales would refer to new prices, which is incorrect. What is needed is a distinction between the historical price when the sale was made, and the current price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        根据信息要求,至少有两种方法可以对此进行建模。一种是简单地将产品价格复制到 SalesLineItem 中,并在 ProductDescriptions 中保持当前价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Depending on the information requirements, there are at least two ways to model this. One is to simply copy the product price into the SalesLineItem, and maintain the current price in the ProductDescriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另一种更可靠的方法是将 ProductPrices 的集合与 ProductDescriptions 相关联,每个集合都有关联的适用时间间隔。因此,组织可以记录所有过去的价格(以解决销售价格问题,并进行趋势分析),还可以记录未来的计划价格(参见图 32.19)。参见 [CLD99] 关于时间间隔的更广泛讨论,在 Moment-Interval 原型类别下。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The other approach, more robust, is to associate a collection of ProductPrices with a ProductDescriptions, each with an associated applicable time interval. Thus, the organization can record all past prices (to resolve the sale price problem, and for trend analysis) and also record future planned prices (see Figure 32.19). See [CLD99] for a broader discussion of time intervals, under the category of Moment-Interval archetypes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 32.19.ProductPrices 和时间间隔。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        通常需要维护时间间隔相关信息的集合,而不是简单的值。物理、医学和科学测量以及许多会计和法律工件都有此要求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        It is common that a collection of time interval related information needs to be maintained, rather than a simple value. Physical, medical, and scientific measurements, and many accounting and legal artifacts have this requirement.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          32.13. 关联角色名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          32.13. Association Role Names

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          关联的每一端都是一个角色,它具有各种属性,例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Each end of an association is a role, which has various properties, such as:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 名字

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • name

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 多样性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • multiplicity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          角色名称标识关联的结束,理想情况下描述关联中的对象所扮演的角色。图 32.20 显示了角色名称示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A role name identifies an end of an association and ideally describes the role played by objects in the association. Figure 32.20 shows role name examples.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 32.20.角色名称。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          显式角色名称不是必需的,当对象的角色不明确时,它很有用。它通常以小写字母开头。如果未显式存在,则假定默认角色名称等于相关类名称,但以小写字母开头。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          An explicit role name is not requiredit is useful when the role of the object is not clear. It usually starts with a lowercase letter. If not explicitly present, assume that the default role name is equal to the related class name, though starting with a lowercase letter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如前所述,在 DCD 中使用的角色可以解释为代码生成期间属性名称的基础。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          As covered previously, roles used in DCDs may be interpreted as the basis for attribute names during code generation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            32.14. 作为概念的角色与关联中的角色

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            32.14. Roles as Concepts versus Roles in Associations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在域模型中,现实世界的角色尤其是人类角色可以通过多种方式进行建模,例如离散概念,或者表示为关联中的角色。[6] 例如,出纳员和经理的角色至少可以用图 32.21 所示的两种方式来表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In a domain model, a real-world roleespecially a human rolemay be modeled in a number of ways, such as a discrete concept, or expressed as a role in an association.[6] For example, the role of cashier and manager may be expressed in at least the two ways illustrated in Figure 32.21.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [6] 为简单起见,没有涵盖其他优秀的解决方案,例如 [Fowler96] 中讨论的那些。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [6] For simplicity, other excellent solutions such as those discussed in [Fowler96] are not covered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 32.21.对人类角色进行建模的两种方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            第一种方法可以称为“关联中的角色”;第二篇是“作为概念的角色”。这两种方法都有优点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The first approach may be called "roles in associations"; the second, "roles as concepts." Both approaches have advantages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            关联中的角色很有吸引力,因为它们是一种相对准确的方式来表达一个人的同一实例在各种关联中扮演多个(并且动态变化)的角色。我,一个人,同时或依次,可以承担写入者、对象设计者、父级等角色。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Roles in associations are appealing because they are a relatively accurate way to express the notion that the same instance of a person takes on multiple (and dynamically changing) roles in various associations. I, a person, simultaneously or in sequence, may take on the role of writer, object designer, parent, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            另一方面,角色作为概念为添加唯一属性、关联和其他语义提供了易用性和灵活性。此外,由于当前流行的面向对象编程语言的限制,将角色实现为单独的类更容易。将一个类的实例动态地改变为另一个类的实例,或者随着人的角色变化动态添加行为和属性是不方便的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            On the other hand, roles as concepts provides ease and flexibility in adding unique attributes, associations, and additional semantics. Furthermore, the implementation of roles as separate classes is easier because of limitations of current popular object-oriented programming languagesit is not convenient to dynamically mutate an instance of one class into another, or dynamically add behavior and attributes as the role of a person changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              32.15. 派生元素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              32.15. Derived Elements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              派生元素可以从其他元素中确定。属性和关联是最常见的派生元素。何时应显示派生元素?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A derived element can be determined from others. Attributes and associations are the most common derived elements. When should derived elements be shown?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              避免在图表中显示派生元素,因为它们会增加复杂性,而不会提供新信息。但是,当派生元素在术语中很突出时,请添加派生元素,并且排除它会影响理解。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Avoid showing derived elements in a diagram, since they add complexity without new information. However, add a derived element when it is prominent in the terminology, and excluding it impairs comprehension.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              例如,Sale 总额可以从 SalesLineItemProductDescriptions 信息中导出(参见图 32.22)。在 UML 中,它以元素名称前的 “/” 显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For example, a Sale total can be derived from SalesLineItem and ProductDescriptions information (see Figure 32.22). In the UML, it is shown with a "/" preceding the element name.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 32.22.派生属性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              作为另一个示例,SalesLineItem 数量实际上是可以从与行项目关联的 Items 实例数中得出的(参见图 32.23)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As another example, a SalesLineItem quantity is actually derivable from the number of instances of Items associated with the line item (see Figure 32.23).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 32.23.与多重性相关的派生属性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                32.16. 合格的关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                32.16. Qualified Associations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                限定符可以在关联中使用;它根据 qualifier 值区分关联远端的对象集。与限定符的关联是限定的关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A qualifier may be used in an association; it distinguishes the set of objects at the far end of the association based on the qualifier value. An association with a qualifier is a qualified association.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如,ProductDescription 可以在 ProductCatalog 中通过其 itemID 进行区分,如图 32.24 (b) 所示。如图 32.24 (a) 与 (b) 所示,限定减少了限定符远端的多重性,通常从多减少到 1。在域模型中描述限定符可以传达在域中,一个类的事物如何与另一个类进行区分。在域模型中,它们不应用于表示有关查找键的设计决策,尽管这适用于说明设计决策的其他图表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For example, ProductDescriptions may be distinguished in a ProductCatalog by their itemID, as illustrated in Figure 32.24 (b). As contrasted in Figure 32.24 (a) vs. (b), qualification reduces the multiplicity at the far end from the qualifier, usually down from many to one. Depicting a qualifier in a domain model communicates how, in the domain, things of one class are distinguished in relation to another class. They should not, in the domain model, be used to express design decisions about lookup keys, although that is suitable in other diagrams illustrating design decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 32.24.合格的协会。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                限定词通常不会添加令人信服的有用新信息,我们可能会陷入“设计-思考”的陷阱。但是,如果使用得当,它们可以加深对该领域的理解。ProductCatalogProductDescriptions 之间的限定关联提供了增值限定符的合理示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Qualifiers do not usually add compelling useful new information, and we can fall into the trap of "design-think." However, used judiciously, they can sharpen understanding about the domain. The qualified associations between ProductCatalog and ProductDescriptions provide a reasonable example of a value-added qualifier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.17. 反身关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  32.17. Reflexive Associations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  概念可能与自身相关联;这被称为反身关联[7](见图 32.25)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A concept may have an association to itself; this is known as a reflexive association[7] (see Figure 32.25).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [7] [MO95] 进一步限制了反身联想的定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  [7] [MO95] constrains the definition of reflexive associations further.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 32.25.反身联想。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.18. 使用 packages 来组织域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    32.18. Using Packages to Organize the Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    域模型很容易变得足够大,以至于需要将其分解为强相关概念的包,以帮助理解和并行分析工作,其中不同的人在不同的子域内进行域分析。以下各节说明了 UP 域模型的包结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A domain model can easily grow large enough that it is desirable to factor it into packages of strongly related concepts, as an aid to comprehension and parallel analysis work in which different people do domain analysis within different sub-domains. The following sections illustrate a package structure for the UP Domain Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    回顾一下,UML 包显示为选项卡式文件夹(参见图 32.26)。从属包可能会显示在其中。如果包描述其元素,则包名称位于选项卡中;否则,它将在文件夹本身内居中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To review, a UML package is shown as a tabbed folder (see Figure 32.26). Subordinate packages may be shown within it. The package name is within the tab if the package depicts its elements; otherwise, it is centered within the folder itself.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.26.一个 UML 包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    所有权和参考资料

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Ownership and References

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    元素由定义它的包拥有,但可以在其他包中引用。在这种情况下,元素名称由包名称使用路径名格式PackageName::ElementName限定(参见图 32.27)。外部包中显示的类可以使用新的关联进行修改,但必须保持不变。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    An element is owned by the package within which it is defined, but may be referenced in other packages. In that case, the element name is qualified by the package name using the pathname format PackageName::ElementName (see Figure 32.27). A class shown in a foreign package may be modified with new associations, but must otherwise remain unchanged.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.27.包中的引用类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    包依赖项

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Package Dependencies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果一个模型元素在某种程度上依赖于另一个模型元素,则依赖关系可能会以依赖关系显示,用箭头线表示。包依赖关系表示依赖包的元素以某种方式了解目标包中的元素或与目标包中的元素耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If a model element is in some way dependent on another, the dependency may be shown with a dependency relationship, depicted with an arrowed line. A package dependency indicates that elements of the dependent package in some way know about or are coupled to elements in the target package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    例如,如果一个包引用另一个包拥有的元素,则存在依赖关系。因此,Sales 包依赖于 Core Elements 包(参见图 32.28)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For example, if a package references an element owned by another, a dependency exists. Thus, the Sales package has a dependency on the Core Elements package (see Figure 32.28).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.28.包依赖项。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如何对域模型进行分区

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How to Partition the Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    域模型中的类应该如何在包中组织?应用以下一般准则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How should the classes in a domain model be organized within packages? Apply the following general guidelines:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    要将域模型划分为多个包,请将元素放在一起:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To partition the domain model into packages, place elements together that:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 属于同一主题领域,在概念或目的上密切相关

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • are in the same subject areaclosely related by concept or purpose

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 一起位于类层次结构中

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • are in a class hierarchy together

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 参与相同的使用案例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • participate in the same use cases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 具有很强的关联性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • are strongly associated



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果与域模型相关的所有元素都植根于一个名为 Domain 的包中,并且所有广泛共享的、通用的核心概念都定义在名为 Core ElementsCommon Concepts 的包中,而没有任何其他有意义的包来放置它们,那么它就很有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It is useful if all elements related to the domain model are rooted in a package called Domain, and all widely shared, common, core concepts are defined in a packaged named something like Core Elements or Common Concepts, in the absence of any other meaningful package within which to place them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    POS 域模型包

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    POS Domain Model Packages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    根据上述标准,POS 域模型的包组织如图 32.29 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Based on the above criteria, the package organization for the POS Domain Model is shown in Figure 32.29.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.29.域概念包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Core/Misc 封装

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Core/Misc Package

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Core/Misc 包(见图 32.30)对于拥有广泛共享的概念或没有明显归宿的概念很有用。在后面的参考中,包名称将缩写为 Core

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A Core/Misc package (see Figure 32.30) is useful to own widely shared concepts or those without an obvious home. In later references, the package name will be abbreviated to Core.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.30.Core 软件包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    此包中没有特定于此迭代的新概念或关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    There are no new concepts or associations particular to this iteration in this package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Payments

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    与迭代 1 一样,新的关联主要由需要知道的标准驱动。例如,需要记住 CreditPaymentCreditCard 之间的关系。相比之下,为了理解,添加了一些关联,例如 DriversLicense Identifies Customer(参见图 32.31)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As in iteration 1, new associations are primarily motivated by a need-to-know criterion. For example, there is a need to remember the relationship between CreditPayment and CreditCard. In contrast, some associations are added more for comprehension, such as DriversLicense Identifies Customer (see Figure 32.31).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.31.付款套餐。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,PaymentAuthorizationReply 表示为关联类。回复源于付款与其授权服务之间的关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note that PaymentAuthorizationReply is expressed as an association class. A reply arises out of association between a payment and its authorization service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    产品

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Products

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    除了复合聚合之外,没有特定于此迭代的新概念或关联(参见图 32.32)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With the exception of composite aggregation, there are no new concepts or associations particular to this iteration (see Figure 32.32).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.32.产品包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sales

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    除了复合聚合和派生属性之外,没有特定于此迭代的新概念或关联(请参见图 32.33)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With the exception of composite aggregation and derived attributes, there are no new concepts or associations particular to this iteration (see Figure 32.33).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.33.销售包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    授权交易

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Authorization Transactions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    尽管建议为关联提供有意义的名称,但在某些情况下,这可能并不引人注目,尤其是当受众认为关联的目的很明显时。一个很好的例子是支付与其交易之间的关联。他们的名字没有指定,因为我们可以假设阅读图 32.34 中的类图的观众会理解这些交易是用于支付的;添加名称只会使图表更加繁忙。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Although providing meaningful names for associations is recommended, in some circumstances it may not be compelling, especially if the purpose of the association is considered obvious to the audience. A case in point is the associations between payments and their transactions. Their names have been left unspecified because we can assume the audience reading the class diagram in Figure 32.34 will understand that the transactions are for the payment; adding the names merely makes the diagram more busy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 32.34.授权交易包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这个图表是不是太详细了,显示了太多的专业化?这要看情况。真正的标准是有用性。虽然它没有错误,但它对提高对领域的理解有什么价值吗?答案应该影响在域模型中要说明的特化数量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Is this diagram too detailed, showing too many specializations? It depends. The real criteria is usefulness. Although it is not incorrect, does it add any value in improving understanding of the domain? The answer should influence how many specializations to illustrate in a domain model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.19. 示例:垄断域模型细化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      32.19. Example: Monopoly Domain Model Refinements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.35 显示了对 Monopoly 域模型的改进。这些包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 32.35 shows refinements to the Monopoly domain model. These include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 不同类型的属性方块(LotSquare 等)。这反映了一个准则,即如果域规则以不同或不同的方式处理一个值得注意的概念,则为其显示单独的专业化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Different kinds of property squares (LotSquare, …). This reflects the guideline that if the domain rules treat a noteworthy concept in a different or distinct manner, then show it a separate specialization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 抽象超类 PropertySquare。这是合理的,因为所有子类都有一个 price 属性和一个 Owns 与 Player关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • An abstract superclass PropertySquare. This is justified because all the subclasses have a price attribute and an Owns association with a Player.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 32.35.迭代 3 垄断领域模型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        第 33 章.架构分析

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Chapter 33. Architectural Analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        错误,无键盘按 F1 继续。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        早期的 PC BIOS 消息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Error, no keyboard press F1 to continue.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        early PC BIOS message

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 创建架构因子表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Create architectural factor tables.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 创建记录架构决策的技术备忘录。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Create technical memos that record architectural decisions.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构分析可以看作是需求分析的一个专业化,它侧重于强烈影响 “架构” 的需求。例如,确定对高度安全的系统的需求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Architectural analysis can be viewed as a specialization of requirements analysis, with a focus on requirements that strongly influence the "architecture." For example, identifying the need for a highly-secure system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构分析的本质是确定应该影响架构的因素,了解它们的可变性和优先级,并解决它们。困难的部分是知道要问什么问题,权衡权衡,并了解解决建筑上重要因素的多种方法,从良性忽视到花哨的设计,再到第三方产品。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The essence of architectural analysis is to identify factors that should influence the architecture, understand their variability and priority, and resolve them. The difficult part is knowing what questions to ask, weighing the trade-offs, and knowing the many ways to resolve an architecturally significant factor, ranging from benign neglect, to fancy designs, to third-party products.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          一个好的建筑师通过拥有知道要问什么问题的经验并选择巧妙的方法来解决这些因素来赚取薪水。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A good architect earns her salary by having the experience to know what questions to ask and choosing skillful means to resolve the factors.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          为什么架构分析很重要?它有助于:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Why is architectural analysis important? It's useful to:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 降低错过系统设计中核心重要内容的风险

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • reduce the risk of missing something centrally important in the design of the systems

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 避免对低优先级问题施加过多的努力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • avoid applying excessive effort to low priority issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 帮助使产品与业务目标保持一致

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • help align the product with business goals

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          本章是从 UP 的角度介绍架构分析的基本步骤和思想;也就是说,要关注方法,而不是 Master Architects 的技巧和窍门。因此,它不是一本架构解决方案的食谱,一个非常大且依赖于上下文的主题,超出了本介绍性书籍的范围。尽管如此,本章中的 NextGen POS 案例研究评论确实提供了架构解决方案的具体示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This chapter is an introduction to basic steps and ideas in architectural analysis from a UP perspective; that is, to the method, rather than to tips and tricks of master architects. Thus, it is not a cookbook of architectural solutionsa very large and context-dependent subject that is beyond the scope of this introductory book. Nevertheless, the NextGen POS case study comments in the chapter do provide concrete examples of architectural solutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            33.1. 过程:我们什么时候开始架构分析?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            33.1. Process: When Do We Start Architectural Analysis?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在 UP 中,架构分析甚至应该在第一次开发迭代之前就开始,因为需要在早期开发工作中识别和解决架构问题。不这样做是高风险的。例如,将“必须国际化以支持英语、中文和印地语”或“必须处理 500 个并发事务,平均响应时间为 1 秒”等架构上重要的因素推迟到开发后期,就会带来痛苦和痛苦。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the UP, architectural analysis should start even before the first development iteration, as architectural issues need to be identified and resolved in early development work. Failure to do so is a high risk. For example, deferring an architecturally-significant factor such as "must be internationalized to support English, Chinese, and Hindi" or "must handle 500 concurrent transactions with on-average one-second response time" until late in development is a recipe for pain and suffering.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            然而,由于 UP 是迭代和进化的,而不是瀑布式的,所以在所有架构分析完成之前,我们在早期迭代中就开始编程和测试。分析和早期开发齐头并进。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            However, since the UP is iterative and evolutionarynot the waterfallwe start programming and testing in early iterations before all the architectural analysis is complete. Analysis and early development proceed hand-in-hand.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            但这个重要的主题被推迟到本书的这一点,以便可以首先介绍 OOA/D 的基本原理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            But this important topic was deferred until this point of the book so that fundamentals of OOA/D could be first presented.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              33.2. 定义:变化点和演变点

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              33.2. Definition: Variation and Evolution Points

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              首先,软件系统中的两个变化点(首先在 Protected Variations 模式中引入)值得重申:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              First, two points of change in a software system (first introduced in the Protected Variations pattern) are worth reiterating:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 变化点现有当前系统或要求的变体,例如必须支持的多个税费计算器界面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • variation point Variations in the existing current system or requirements, such as the multiple tax calculator interfaces that must be supported.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 进化点将来可能出现但未出现在现有要求中的推测性变化点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • evolution point Speculative points of variation that may arise in the future, but which are not present in the existing requirements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              正如我们将看到的,变化点和演变点是架构分析中反复出现的关键元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As will be seen, variation and evolution points are recurring key elements in architectural analysis.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                33.3. 架构分析

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                33.3. Architectural Analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                架构分析涉及在功能需求(例如,处理销售)的上下文中识别和解决系统的非功能需求(例如,安全性)。它包括识别变化点和最可能的演变点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Architectural analysis is concerned with the identification and resolution of the system's non-functional requirements (for example, security), in the context of the functional requirements (for example, processing sales). It includes identifying variation points and the most probable evolution points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                在 UP 中,该术语包括建筑调查(识别)和建筑设计(分辨率)。以下是在架构级别需要识别和解决的许多问题的一些示例:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the UP, the term encompasses both architectural investigation (identification) and architectural design (resolution). Here are some examples of the many issues to be identified and resolved at an architectural level:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 可靠性和容错要求如何影响设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 例如,在 NextGen POS 中,哪些远程服务(例如,税收计算器)将允许故障转移到本地服务?为什么?他们在本地提供的服务是否与远程服务完全相同,或者是否存在差异?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How do reliability and fault-tolerance requirements affect the design?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • For example, in the NextGen POS, for what remote services (e.g., tax calculator) will fail-over to local services be allowed? Why? Do they provide exactly the same services locally as remotely, or are there differences?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 购买的子组件的许可成本如何影响盈利能力?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 例如,出色的数据库服务器 Clueless 的生产商希望从每次 NextGen POS 销售中获得 2%,如果他们的产品用作子组件。使用他们的产品将加快开发速度(和上市时间),因为它功能强大,提供许多服务,许多开发人员都知道这一点,但价格合理。团队是否应该使用不太健壮的开源 YourSQL 数据库服务器?面临什么风险?它如何限制 NextGen 产品的充电能力?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How do the licensing costs of purchased subcomponents affect profitability?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • For example, the producer of the excellent database server, Clueless, wants 2% of each NextGen POS sale, if their product is used as a subcomponent. Using their product will speed development (and time to market) because it is robust and provides many services, and many developers know it, but at a price. Should the team instead use the less robust, open source YourSQL database server? At what risk? How does it restrict the ability to charge for the NextGen product?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 适应性和可配置性要求如何影响设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 例如,大多数零售商都希望在其 POS 应用程序中表示业务规则。有哪些变化?为他们设计的“最佳”方式是什么?最佳标准是什么?NextGen 能否通过要求为每个客户定制编程(以及这将付出多少努力?)或通过允许客户自己轻松添加定制的解决方案来赚取更多的钱?“更多的钱”应该是短期的目标吗?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How do the adaptability and configurability requirements affect the design?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • For example, most retailers have variations in business rules they want represented in their POS applications. What are the variations? What is the "best" way to design for them? What is the criteria for best? Can NextGen make more money by requiring customized programming for each customer (and how much effort will that be?), or with a solution that allows the customer to add the customization easily themselves? Should "more money" be the goal in the short-run?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 品牌名称和品牌如何影响架构?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 一个鲜为人知的故事是,Microsoft 的 Windows XP 最初并不被命名为“Windows XP”。这个名字是营销部门在最后一刻才做出的改变。您可能会发现,操作系统名称以原始文本和图形图像的形式显示在许多位置。由于 Microsoft 架构师未将名称更改确定为可能的演变点,因此没有针对该点的受保护变体解决方案,例如标签仅存在于配置文件中的一个位置。因此,在最后一刻,一个小团队搜索了数百万行源代码和图像文件,并进行了数百次更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 同样,NextGen 商品的品牌名称和相关徽标、图标等的潜在更改应如何影响其架构?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How does brand name and branding affect the architecture?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • A little-known story is that Microsoft's Windows XP was not originally named "Windows XP." The name was a relatively last-minute change from the marketing department. You may appreciate that the operating system name is displayed in many places, both as raw text and as a graphic image. Because the Microsoft architects did not identify a name change as a likely evolution point, there was no Protected Variation solution for this point, such as the label existing in only one place in a configuration file. Therefore, at the last minute, a small team scoured the millions of lines of source code and image files, and made hundreds of changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Similarly, how should potential changes to the brand name of the NextGen product and related logos, icons, and so forth affect its architecture?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 适应性和可配置性要求如何影响设计?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 例如,大多数零售商都希望在其 POS 应用程序中表示业务规则。有哪些变化?为他们设计的“最佳”方式是什么?最佳标准是什么?Next Gen 能否通过要求为每个客户定制编程(以及这将付出多少努力?)或通过允许客户自己轻松添加定制的解决方案来赚更多的钱?“更多的钱”应该是短期的目标吗?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • How do the adaptability and configurability requirements affect the design?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • For example, most retailers have variations in business rules they want represented in their POS applications. What are the variations? What is the "best" way to design for them? What is the criteria for best? Can Next Gen make more money by requiring customized programming for each customer (and how much effort will that be?), or with a solution that allows the customer to add the customization easily themselves? Should "more money" be the goal in the short-run?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  33.4. 架构分析中的常用步骤

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  33.4. Common Steps in Architectural Analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  架构分析有几种方法。大多数步骤的共同点是以下步骤的一些变体:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  There are several methods of architectural analysis. Common to most of these is some variation of the following steps:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  识别并分析对架构有影响的非功能性需求。功能需求也是相关的(尤其是在可变性或变化方面),但非功能性需求得到了彻底的关注。通常,所有这些都可以称为架构因素(也称为架构驱动因素)。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 此步骤可以被描述为常规需求分析,但由于它是在识别架构影响和决定高级架构解决方案的背景下完成的,因此它被认为是 UP 中架构分析的一部分。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • This step could be characterized as regular requirements analysis, but since it is done in the context of identifying architectural impact and deciding high-level architectural solutions, it is considered a part of architectural analysis in the UP.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 就 UP 而言,其中一些需求将在 Supplementary Specification 或初期的用例中得到粗略识别和记录。在架构分析期间(发生在早期细化中),团队会更仔细地研究这些需求。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • In terms of the UP, some of these requirements will be roughly identified and recorded in the Supplementary Specification or use cases during inception. During architectural analysis, which occurs in early elaboration, the team investigates these requirements more closely.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  对于具有重大架构影响的需求,分析替代方案并创建解决影响的解决方案。这些是架构决策



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 决策范围从“删除需求”到自定义解决方案,再到“停止项目”,再到“聘请专家”。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Decisions range from "remove the requirement," to a custom solution, to "stop the project," to "hire an expert."



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  本演示文稿在 NextGen POS 案例研究的背景下介绍了这些基本步骤。为简单起见,它避免了架构部署问题,例如硬件和操作系统配置,这些问题对上下文和时间非常敏感。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This presentation introduces these basic steps in the context of the NextGen POS case study. For simplicity, it avoids architectural deployment issues such as the hardware and operating system configuration, which are very context and time sensitive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    33.5. 科学:建筑因素的识别和分析

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    33.5. The Science: Identification and Analysis of Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    架构因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    任何和所有 FURPS+ 要求都可能对系统的体系结构产生重大影响,范围从可靠性到进度、技能和成本限制。例如,如果时间紧迫,技能有限,资金充足,则可能倾向于购买或外包给专家,而不是在内部构建所有组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Any and all of the FURPS+ requirements may have a significant influence on the architecture of a system, ranging from reliability, to schedule, to skills, and to cost constraints. For example, a case of tight schedule with limited skills and sufficient money probably favors buying or outsourcing to specialists, rather than building all components in-house.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    FURPS+ 第 56

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    FURPS+ p. 56



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    但是,体系结构影响最强的因素往往属于功能、可靠性、性能、可支持性、实现和接口的高级 FURPS+ 类别。有趣的是,通常是非功能性质量属性(例如可靠性或性能)赋予特定架构独特的风格,而不是其功能要求。例如,NextGen 系统中的设计支持具有独特接口的不同第三方组件,以及支持轻松插入不同业务规则集的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    However, the factors with the strongest architectural influence tend to be within the high-level FURPS+ categories of functionality, reliability, performance, supportability, implementation, and interface. Interestingly, it is usually the non-functional quality attributes (such as reliability or performance) that give a particular architecture its unique flavor, rather than its functional requirements. For example, the design in the NextGen system to support different third-party components with unique interfaces, and the design to support easily plugging in different sets of business rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在 UP 中,这些具有体系结构影响的因素称为体系结构上的重要要求。为简洁起见,此处使用 “Factors” 。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In the UP, these factors with architectural implications are called architecturally significant requirements. "Factors" is used here for brevity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    许多技术和组织因素可以被描述为以某种方式限制解决方案的约束(例如,必须在 Linux 上运行,或者购买第三方组件的预算是 X)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Many technical and organizational factors can be characterized as constraints that restrict the solution in some way (such as, must run on Linux, or, the budget for purchasing third-party components is X).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    质量场景

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Quality Scenarios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在架构因素分析期间定义质量要求时,建议使用质量方案[1],因为它们定义了可测量(或至少可观察)的响应,因此可以验证。模糊地说“系统将很容易修改”,而没有衡量其含义,这没有多大用处。[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    When defining quality requirements during architectural factor analysis, quality scenarios[1] are recommended, as they define measurable (or at least observable) responses, and thus can be verified. It is not much use to vaguely state "the system will be easy to modify" without some measure of what that means.[2]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] 软件工程研究所 (SEI) 推广的各种架构方法中使用的术语;例如,在 Architecture Based Design 方法中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [1] A term used in various architectural methods promoted by the Software Engineering Institute (SEI); for example, in the Architecture Based Design method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [2] 汤姆·吉尔布 (Tom Gilb) 可能是第一个迭代和进化方法 Evo 的创造者,他也是量化和测量非功能性目标需求的长期支持者。他的 PLanguage 结构化需求语言强调量化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [2] Tom Gilb, the creator of perhaps the first iterative and evolutionary method, Evo, is also a long-time proponent of the need to quantify and measure non-functional goals. His PLanguage structured requirements language emphasizes quantification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    量化某些内容(例如性能目标和平均故障间隔时间)是众所周知的做法,但质量方案扩展了这一概念,并鼓励将所有(或至少大多数)因素记录为可衡量的陈述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Quantifying some things, such as performance goals and mean time between failure, are well known practices, but quality scenarios extend this idea and encourage recording all (or at least, most) factors as measurable statements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    质量情景是以下形式的简短陈述<刺激> <可衡量的反应>;例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Quality scenarios are short statements of the form <stimulus> <measurable response>; for example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 当完成的销售被发送到远程税收计算器以添加税款时,结果将在“大多数”时间内返回 2 秒,在“平均”负载条件下的生产环境中测量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • When the completed sale is sent to the remote tax calculator to add the taxes, the result is returned within 2 seconds "most" of the time, measured in a production environment under "average" load conditions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 当 NextGen Beta 版测试志愿者收到错误报告时,请在 1 个工作日内通过电话回复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • When a bug report arrives from a NextGen beta test volunteer, reply with a phone call within 1 working day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,“大多数”和“平均”需要 NextGen 架构师进一步调查和定义;质量场景在可测试之前并不真正有效,这意味着完全指定。此外,根据 First Quality 方案中的限定条件,请根据其适用的环境来观察限定条件。指定质量方案,验证它是否在轻负载开发环境中通过,但无法在实际生产环境中评估它,它没有什么用处。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note that "most" and "average" will need further investigation and definition by the NextGen architect; a quality scenario is not really valid until it is testable, which implies fully specified. Also, observe the qualification in the first quality scenario in terms of the environment to which it applies. It does little good to specify a quality scenario, verify that it passes in a lightly loaded development environment, but fail to evaluate it in a realistic production environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    选择你的战斗

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    注意事项:编写这些质量场景可能是一个有用的海市蜃楼。编写这些详细的规范很容易,但实现它们却不容易。有人真的会测试它们吗?如何以及由谁?写这些时需要强烈的现实主义;如果没有人真正跟进测试它们,那么列出许多复杂的目标就没有意义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A caution: Writing these quality scenarios can be a mirage of usefulness. It's easy to write these detailed specifications, but not to realize them. Will anyone ever really test them? How and by whom? A strong dose of realism is required when writing these; there's no point in listing many sophisticated goals if no one will ever really follow through on testing them.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这与前面一章中关于 Protected Variations 模式的 “pick your battles” 讨论有关系。真正关键的成败质量场景是什么?例如,在航空公司预订系统中,在非常高的负载条件下始终如一地快速完成事务对于系统的成功至关重要,这绝对必须进行测试。在 NextGen 系统中,应用程序确实必须具有容错能力,并在远程服务失败时故障转移到本地复制服务,这绝对必须经过适当的测试和验证。因此,请专注于为重要战斗编写质量场景,并遵循评估计划。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    There is a relationship here to the "pick your battles" discussion that was presented in an earlier chapter on the Protected Variations pattern. What are the really critical make-or-break quality scenarios? For example, in an airline reservation system, consistently fast transaction completion under very high load conditions is truly critical to the success of the systemit must definitely be tested. In the NextGen system, the application really must be fault-tolerant and fail over to local replicated services when the remote ones failit must definitely be properly tested and validated. Therefore, focus on writing quality scenarios for the important battles, and follow through with a plan for their evaluation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    描述因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Describing Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    架构分析的一个重要目标是了解这些因素的影响、它们的优先级和可变性(对灵活性和未来演变的迫切需求)。因此,大多数体系结构方法(例如,请参阅 [HNS00])都主张创建包含以下信息变体的表或树(格式因方法而异)。表 33.1 中所示的以下样式称为系数表,在 UP 中是补充规范的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    One important goal of architectural analysis is to understand the influence of the factors, their priorities, and their variability (immediate need for flexibility and future evolution). Therefore, most architectural methods (for example, see [HNS00]) advocate creating a table or tree with variations of the following information (the format varies depending on the method). The following style shown in Table 33.1 is called a factor table, which in the UP is part of the Supplementary Specification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    表 33.1.样本因子表。图例:H-high。M 中号。SME 主题专家。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Factor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    度量和质量方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Measures and quality scenarios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    可变性(当前的灵活性和未来的演变)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Variability (current flexibility and future evolution)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因素(及其可变性)对利益相关者、架构和其他因素的影响

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Impact of factor (and its variability) on stakeholders, architecture and other factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    成功优先

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Priority for Success

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    困难或风险

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Difficulty or Risk

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    可靠性可恢复性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ReliabilityRecoverability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    从远程服务故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Recovery from remote service failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    当远程服务发生故障时,在生产环境中的正常存储负载下,在检测到其重新可用性后的 1 分钟内重新建立与该服务的连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    When a remote service fails, reestablish connectivity with it within 1 minute of its detected re-availability, under normal store load in a production environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    当前的灵活性 - 我们的 SME 表示,在可以重新连接之前,本地客户端简化服务是可以接受的(也是可取的)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    current flexibility - our SME says local client-side simplified services are acceptable (and desirable) until reconnection is possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Evolution - 在 2 年内,一些零售商可能愿意为远程服务的完全本地复制付费(例如税收计算器)。概率?高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    evolution - within 2 years, some retailers may be willing to pay for full local replication of remote services (such as the tax calculator). Probability? High.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    对大型设计影响大。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    High impact on the large-scale design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    当远程服务失败时,零售商真的很不喜欢它,因为它会阻止或限制他们使用 POS 进行销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Retailers really dislike it when remote services fail, as it prevents or restricts them from using a POS to make sales.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意分类方案:ReliabilityRecoverability(来自 FURPS+ 类别)。这并不是最佳方案或唯一的方案,但将架构因素分组到各个类别中非常有用。例如,某些类别(比如可靠性和性能)与标识和定义测试计划密切相关,因此对它们进行分组非常有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Notice the categorization scheme: ReliabilityRecoverability (from the FURPS+ categories). This isn't presented as the best or only scheme, but it is useful to group architectural factors into categories. For example, certain categories (such as reliability and performance) strongly relate to identifying and defining test plans, and thus it is useful to group them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    H/M/L 的基本优先级和风险代码值只是建议使用团队认为有用的一些代码;有来自不同架构方法和标准 (如 ISO 9126) 的各种编码方案 (数字和定性) 。注意:如果使用更复杂的方案的额外努力没有导致任何实际行动,那么它就不值得。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The basic priority and risk code values of H/M/L are simply suggestive of using some codes the team finds useful; there are a variety of coding schemes (numeric and qualitative) from different architectural methods and standards (such as ISO 9126). A caution: If the extra effort of using a more complex scheme does not lead to any practical action, it isn't worthwhile.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因子和 UP 伪影

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Factors and UP Artifacts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    UP 中的中心功能需求存储库是用例,它们与愿景和补充规范一起,是创建因子表时的重要灵感来源。在用例中,应审查特殊要求、技术变体未解决的问题,并将其隐含或明确的架构因素整合到补充规范中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The central functional requirements repository in the UP are the use cases, and they, along with the Vision and Supplementary Specification, are an important source of inspiration when creating a factor table. In the use cases, the Special Requirements, Technology Variations, and Open Issues should be reviewed, and their implied or explicit architectural factors consolidated in the Supplementary Specification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    由于明显的关系,在创建用例期间首先记录与用例相关的因素是合理的,但最终将所有架构因素合并到补充规范的因子表中的一个位置会更方便(在内容管理、跟踪和可读性方面)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It is reasonable to at first record use-case related factors with the use case during its creation, because of the obvious relationship, but it is ultimately more convenient (in terms of content management, tracking, and readability) to consolidate all the architectural factors in one locationin the factor table in the Supplementary Specification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    用例 UC1:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    特殊要求:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Special Requirements:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - 在 90% 的时间内在 30 秒内完成积分授权响应。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - Credit authorization response within 30 seconds 90% of the time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - 不知何故,我们希望在访问远程服务(如库存系统)失败时进行稳健的恢复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - Somehow, we want robust recovery when access to remote services such the inventory system is failing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - …

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - …

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    技术和数据变体列表:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Technology and Data Variations List:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2a.通过条形码激光扫描仪(如果存在条形码)或键盘输入的项目标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2a. Item identifier entered by bar code laser scanner (if bar code is present) or keyboard.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    未解决的问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Open Issues:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - 税法有哪些变化?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - What are the tax law variations?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - 探索远程服务恢复问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    - Explore the remote service recovery issue.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      33.6. 示例:部分 NextGen POS 架构因子表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      33.6. Example: Partial NextGen POS Architectural Factor Table

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      表 33.2 中的部分因子表显示了与后面讨论相关的一些因子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The partial factor table in Table 33.2 shows some factors related to later discussion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      表 33.2.NextGen 架构分析的偏因子表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Factor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      度量和质量方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Measures and quality scenarios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      可变性(当前的灵活性和未来的演变)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Variability (current flexibility and future evolution)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因素(及其可变性)对利益相关者、架构和其他因素的影响

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Impact of factor (and its variability) on stakeholders, architecture and other factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      成功优先

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Priority for Success

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      困难或风险

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Difficulty or Risk

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      可靠性可恢复性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ReliabilityRecoverability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      从远程服务故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Recovery from remote service failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当远程服务发生故障时,在生产环境中的正常存储负载下,在检测到其重新可用性后的 1 分钟内重新建立与该服务的连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When a remote service fails, reestablish connectivity with it within 1 minute of its detected re-availability, under normal store load in a production environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当前的灵活性 - 我们的 SME 表示,在可以重新连接之前,本地客户端简化服务是可以接受的(也是可取的)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current flexibility - our SME says local client-side simplified services are acceptable (and desirable) until reconnection is possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Evolution - 在 2 年内,一些零售商可能愿意为远程服务的完全本地复制付费(例如税收计算器)。概率?高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      evolution - within 2 years, some retailers may be willing to pay for full local replication of remote services (such as the tax calculator). Probability? High.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对大型设计影响大。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      High impact on the large-scale design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当远程服务失败时,零售商真的很不喜欢它,因为它会阻止他们使用 POS 进行销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Retailers really dislike it when remote services fail, as it prevents them from using a POS to make sales.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      从远程产品数据库故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Recovery from remote product database failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      同上

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      as above

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当前的灵活性 - 我们的 SME 表示,在可以重新连接之前,本地客户端使用缓存的“最常见”产品信息是可以接受的(也是可取的)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current flexibility - our SME says local client-side use of cached "most common" product info is acceptable (and desirable) until reconnection is possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      演进 - 在 3 年内,客户端大容量存储和复制解决方案将变得便宜且有效,允许永久完整复制,从而在本地使用。概率?高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      evolution - within 3 years, client-side mass storage and replication solutions will be cheap and effective, allowing permanent complete replication and thus local usage. Probability? High.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      同上

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      as above

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      M

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      可支持性 - 适应性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Supportability - Adaptability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      支持许多第三方服务(税务计算器、库存、人力资源、会计)。它们在每次安装时都会有所不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Support many third-party services (tax calculator, inventory, HR, accounting). They will vary at each installation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当必须集成新的第三方系统时,可以集成,并且只需 10 个人天即可完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When a new third-party system must be integrated, it can be, and within 10 person days of effort.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当前灵活性 - 如因子所述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current flexibility - as described by factor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      演变 - 无

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      evolution - none

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      商品验收时必填项。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Required for product acceptance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对设计影响小。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Small impact on design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      是否支持 POS 客户端的无线 PDA 终端?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Support wireless PDA terminals for the POS client?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      添加支持后,不需要更改体系结构的非 UI 层的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When support is added, it does not require a change to the design of the non-UI layers of the architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当前灵活性 - 目前不需要

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current flexibility - not required at present

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      演变 - 在 3 年内,我们认为市场需要无线“PDA”POS 客户端的可能性非常高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      evolution - within 3 years, we think the probability is very high that wireless "PDA" POS clients will be desired by the market.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在受许多元素保护的变化方面具有很高的设计影响。例如,小型设备上的操作系统和 UI 不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      High design impact in terms of protected variation from many elements. For example, the operating systems and UIs are different on small devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      其他 - 法律声明

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Other - Legal

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      必须应用当前的税务规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Current tax rules must be applied.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当审核员评估一致性时,将发现 100% 的一致性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When the auditor evaluates conformance, 100% conformance will be found.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当税收规则发生变化时,它们将在政府允许的期限内运行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When tax rules change, they will be operational within the period allowed by government.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当前的灵活性 - 合规性不灵活,但由于政府税收的许多规则和级别(国家、州等),税收规则几乎每周都会发生变化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      current flexibility - conformance is inflexible, but tax rules can change almost weekly because of the many rules and levels of government taxation (national, state, ...)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      演变 - 无

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      evolution - none

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      不遵守规定是刑事犯罪。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Failure to comply is a criminal offense.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      影响税务计算服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Impacts tax calculation services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      我们自己写服务难——规则复杂,变化不断,需要跟踪各级政府。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Difficult to write our own service--complex rules, constant change, need to track all levels of government.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      但是,如果购买套餐,则简单/低风险。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      But, easy/low risk if buy a package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      H

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      L



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        33.7. 艺术:建筑因素的解析

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        33.7. The Art: Resolution of Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        可以说,建筑科学是有关建筑因素的信息的集合和组织,如因子表中所示。建筑的艺术在于根据权衡、相互依赖关系和优先级做出巧妙的选择来解决这些因素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        One could say the science of architecture is the collection and organization of information about the architectural factors, as in the factor table. The art of architecture is making skillful choices to resolve these factors, in light of trade-offs, interdependencies, and priorities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        熟练的架构师拥有各个领域的知识(例如,架构风格和模式、技术、产品、陷阱和趋势),并将其应用于他们的决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Adept architects have knowledge in a variety of areas (for example, architectural styles and patterns, technologies, products, pitfalls, and trends) and apply this to their decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        记录架构替代方案、决策和动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Recording Architectural Alternatives, Decisions, and Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        暂时忽略架构决策的原则,几乎所有的架构方法都建议记录值得注意的问题和决策的替代解决方案、决策、影响因素和动机。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Ignoring for now principles of architectural decision-making, virtually all architectural methods recommend keeping a record of alternative solutions, decisions, influential factors, and motivations for the noteworthy issues and decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这些记录被称为技术备忘录 [Cunningham96]、发行卡 [HNS00] 和架构方法文档 (SEI 架构提案),具有不同程度的正式性和复杂性。在某些方法中,这些备忘录是另一步审查和改进的基础。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Such records have been called technical memos [Cunningham96], issue cards [HNS00], and architectural approach documents (SEI architectural proposals), with varying degrees of formality and sophistication. In some methods, these memos are the basis for yet another step of review and refinement.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UP 中,备忘录应记录在 SAD 中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UP, the memos should be recorded in the SAD.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        技术备忘录的一个重要方面是动机或理由。当未来的开发人员或架构师需要修改系统时,[3] 了解设计背后的动机非常有帮助,例如为什么选择了从 NextGen POS 中的远程服务故障中恢复的特定方法而拒绝了其他方法,以便做出有关更改系统的明智决策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An important aspect of the technical memo is the motivation or rationale. When a future developer or architect needs to modify the system,[3] it is immensely helpful to understand the motivations behind the design, such as why a particular approach to recovery from remote service failure in the NextGen POS was chosen and others rejected, in order to make informed decisions about changing the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [3] 或者当四个星期过去了,最初的架构师忘记了他们自己的理由时!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [3] Or when four weeks have passed and the original architect has forgotten their own rationale!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        解释拒绝替代方案的理由很重要,因为在未来的产品发展过程中,架构师可能会重新考虑这些替代方案,或者至少想知道考虑了哪些替代方案,以及为什么选择其中一个。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explaining the rationale of rejecting the alternatives is important, as during future product evolution, an architect may reconsider these alternatives, or at least want to know what alternatives were considered, and why one was chosen.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        下面是一个示例技术备忘录,其中记录了 NextGen POS 的架构决策。当然,确切的格式并不重要。保持简单,只记录有助于未来读者在更改系统时做出明智决定的信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A sample technical memo follows that records an architectural decision for the NextGen POS. The exact format is, of course, not important. Keep it simple and just record information that will help the future reader make an informed decision when changing the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        技术备忘录:问题:可靠性从远程服务故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Technical Memo: Issue: ReliabilityRecovery from Remote Service Failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        解决方案摘要:使用服务查找、从远程到本地的故障转移以及本地服务部分复制实现位置透明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution Summary: Location transparency using service lookup, failover from remote to local, and local service partial replication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 从远程服务故障(例如,税收计算器、库存)中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Robust recovery from remote service failure (e.g., tax calculator, inventory)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 从远程产品(例如描述和价格)数据库故障中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Robust recovery from remote product (e.g., descriptions and prices) database failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        使用在 ServicesFactory 中创建的 Adapter 实现服务位置的受保护变体。在可能的情况下,提供远程服务的本地实现,通常具有简化或约束的行为。例如,当地税计算器将使用固定税率。本地产品信息数据库将是最常见产品的一小块缓存。库存更新将在重新连接时存储和转发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Achieve protected variation with respect to location of services using an Adapter created in a ServicesFactory. Where possible, offer local implementations of remote services, usually with simplified or constrained behavior. For example, the local tax calculator will use constant tax rates. The local product information database will be a small cache of the most common products. Inventory updates will be stored and forwarded at reconnection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另请参阅适应性第三方服务技术备忘录,了解此解决方案的适应性方面,因为远程服务实施在每次安装时都会有所不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        See also the AdaptabilityThird-Party Services technical memo for the adaptability aspects of this solutions, because remote service implementations will vary at each installation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        为了满足尽快与远程服务重新连接的质量方案,请对服务使用智能代理对象,在每次服务调用时测试远程服务重新激活,并在可能的情况下重定向到它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To satisfy the quality scenarios of reconnection with the remote services ASAP, use smart Proxy objects for the services, that on each service call test for remote service reactivation, and redirect to them when possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        零售商真的不想停止销售!因此,如果 NextGen POS 提供这种级别的可靠性和恢复能力,它将是一款非常有吸引力的产品,因为我们的竞争对手都没有提供这种功能。小型产品缓存是由非常有限的客户端资源驱动的。真正的第三方税务计算器不会在客户端上复制,主要是因为许可成本和配置工作较高(因为每个计算器安装几乎每周都需要调整一次)。这种设计还支持未来客户的演变点,他们愿意并能够将税收计算器等服务永久复制到每个客户端。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Retailers really don't want to stop making sales! Therefore, if the NextGen POS offers this level of reliability and recovery, it will be a very attractive product, as none of our competitors provide this capability. The small product cache is motivated by very limited client-side resources. The real third-party tax calculator is not replicated on the client primarily because of the higher licensing costs, and configuration efforts (as each calculator installation requires almost weekly adjustments). This design also supports the evolution point of future customers willing and able to permanently replicate services such as the tax calculator to each client terminal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        未解决的问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Unresolved Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        没有

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        none

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        考虑的替代方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Alternatives Considered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        “黄金级”服务质量协议,提供远程信用授权服务,以提高可靠性。它可用,但太贵了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A "gold level" quality of service agreement with remote credit authorization services to improve reliability. It was available, but much too expensive.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        请注意,如本示例所示,这是一个关键点,一个技术备忘录中描述的架构决策可以解决一组因素,而不仅仅是一个因素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Note as illustrated in this exampleand this is a key pointthat an architectural decision described in one technical memo may resolve a group of factors, not only one.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        优先 级

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Priorities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有一个指导架构决策的目标层次结构:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There is a hierarchy of goals that guides architectural decisions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 不灵活的约束,包括安全和法律合规性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • NextGen POS 必须正确应用税务政策。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Inflexible constraints, including safety and legal compliance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The NextGen POS must correctly apply tax policies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 业务目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 值得注意的功能演示,为 18 个月后在汉堡举行的 POSWorld 贸易展做好准备。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 具有对欧洲百货公司有吸引力的品质和功能(例如,多币种支持和可自定义的业务规则)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. Business goals.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Demo of noteworthy features ready for the POSWorld trade show in Hamburg in 18 months.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Has qualities and features attractive to department stores in Europe (for example, multi-currency support and customizable business rules).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        5. 所有其他目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 这些通常可以追溯到直接陈述的业务目标,但都是间接的。例如,“易于扩展:可以在 10 个人周内添加<一些功能单元>”可以追溯到“每六个月发布一次新版本”的业务目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        6. All other goals

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • These can often be traced back to directly stated business goals, but are indirect. For example, "easily extendible: can add <some unit of functionality> in 10 person weeks" could trace to a business goal of "new release every six months."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UP 中,其中许多目标都记录在 Vision 工件中。请记住,因素表中的 Priority for Success 分数应反映这些目标的优先级。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UP, many of these goals are recorded in the Vision artifact. Mind that the Priority for Success scores in the factor table should reflect the priority of these goals.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        与小规模对象设计相比,这个级别的决策有一个区别:人们必须同时考虑更多(通常是具有全球影响力的)目标及其权衡。此外,业务目标成为技术决策的核心(或者至少它们应该如此)。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There is a distinguishing aspect of decision-making at this level vs. small-scale object design: one has to simultaneously consider more (and often globally influential) goals and their trade-offs. Furthermore, the business goals become central to the technical decisions (or at least they should). For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        技术备忘录:问题:法律税务规则合规性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Technical Memo: Issue: LegalTax Rule Compliance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        解决方案摘要:购买税计算器组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution Summary: Purchase a tax calculator component.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 必须依法适用现行税务规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Current tax rules must be applied, by law.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        购买带有许可协议的税收计算器,以接收持续的税收规则更新。请注意,不同的安装可能会使用不同的计算器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Purchase a tax calculator with a licensing agreement to receive ongoing tax rule updates. Note that different calculators may be used at different installations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        上市时间、正确性、低维护要求和满意的开发人员(参见替代方案)。这些产品成本高昂,这会影响我们的成本控制和产品定价业务目标,但替代方案被认为是不可接受的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Time-to-market, correctness, low maintenance requirements, and happy developers (see alternatives). These products are costly, which affects our cost-containment and product pricing business goals, but the alternative is considered unacceptable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        未解决的问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Unresolved Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        主导产品及其质量是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        What are the leading products and their qualities?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        考虑的替代方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Alternatives Considered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        由 NextGen 团队构建一个?据估计,这需要很长时间,容易出错,并且会产生持续的昂贵且无趣的维护责任(对公司的开发人员来说),这会影响“快乐的开发人员”的目标(当然,这是最重要的目标)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Build one by the NextGen team? It is estimated to take too long, be error prone, and create an ongoing costly and uninteresting (to the company's developers) maintenance responsibility, which affects the goal of "happy developers" (surely, the most important goal of all).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        优先事项和演变点:设计不足和过度设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        架构决策的另一个显著特征是按演变的概率、变化点、未来可能出现的变化点或变化点进行优先级排序。例如,在 NextGen 中,无线手持客户端终端有可能成为可取的。由于操作系统、用户界面、硬件资源等方面的差异,为此进行设计会产生重大影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Another distinguishing feature of architectural decision-making is prioritization by probability of evolution pointspoints of variability or change that may arise in the future. For example, in NextGen, there is a chance that wireless handheld client terminals will become desirable. Designing for this has a significant impact because of differences in operating systems, user interface, hardware resources, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        公司可能会花费大量资金(并增加各种风险)来实现这种“面向未来”。如果将来证明这无关紧要,那么这样做将是一项非常昂贵的过度工程练习。还要注意,未来证明可以说很少是完美的,因为它是推测;即使发生了预测的变化,推测的设计也可能发生一些变化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The company could spend a huge amount of money (and increase a variety of risks) to achieve this "future proofing." If it turns out in the future that this was not relevant, doing it would be a very expensive exercise in over-engineering. Note also that future proofing is arguably rarely perfect, since it is speculation; even if the predicted change occurs, some change in the speculated design is likely.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另一方面,针对 Y2K 日期问题的未来证明将是花得非常好的钱;相反,存在着设计不足的结果,结果非常昂贵。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        On the other hand, future proofing against the Y2K date problem would have been money very well spent; instead, there was under-engineering with a wickedly expensive result.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        建筑师的艺术是知道哪些战斗值得打在哪里值得投资于提供保护以防止进化变化的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The art of the architect is knowing what battles are worth fightingwhere it's worth investing in designs that provide protection against evolutionary change.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        要决定是否应该避免早期的“面向未来”,请现实地考虑将更改推迟到未来需要时的情况。实际上需要更改多少设计和代码?将付出什么努力?也许仔细观察潜在的变化会发现,最初被认为是一个巨大的保护问题,估计只需要几个人周的努力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To decide if early "future-proofing" should be avoided, realistically consider the scenario of deferring the change to the future, when it is called for. How much of the design and code will actually have to change? What will be the effort? Perhaps a close look at the potential change will reveal that what was at first considered a gigantic issue to protect against, is estimated to consume only a few person-weeks of effort.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这只是一个难题;“预测非常困难,尤其是当它与未来有关时”(无法验证地归因于 Niels Bohr)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This is just a hard problem; "Prediction is very difficult, especially if it's about the future" (unverifiably attributed to Niels Bohr).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        基本架构设计原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Basic Architectural Design Principles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本书中探讨的适用于小规模对象设计的核心设计原则仍然是大规模架构级别的主导原则:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The core design principles explored in much of this book that were applicable to small-scale object design are still dominant principles at the large-scale architectural level:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • low coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 高内聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • high cohesion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 受保护的变体(接口、间接寻址、服务查找等)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • protected variation (interfaces, indirection, service lookup, and so forth)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        但是,组件的粒度更大,因为应用程序、子系统或流程之间的耦合度较低,而不是小对象之间的低耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        However, the granularity of the components is largerit is low coupling between applications, subsystems, or process rather than between small objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此外,在这种更大的尺度上,有更多或不同的机制可以实现低耦合和受保护的变化等品质。例如,请考虑以下技术备忘录:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Furthermore, at this larger scale, there are more or different mechanisms to achieve qualities such as low coupling and protected variation. For example, consider this technical memo:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        技术备忘录:问题:适应性第三方服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Technical Memo: Issue: AdaptabilityThird-Party Services

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        解决方案摘要:使用接口和适配器的受保护变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution Summary: Protected Variation using interfaces and Adapters

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 支持许多多变的第三方服务(税务计算器、信用授权、库存......

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Support many, changeable third-party services (tax calculators, credit authorization, inventory, ...)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        按如下方式实现受保护的变体:分析多个商业税计算器产品(以及其他产品类别的此类推),并为功能的最低公分母构建通用接口。然后通过 Adapter 模式使用 Indirection。也就是说,创建一个资源 Adapter 对象,该对象实现接口并充当特定后端税计算器的连接和转换器。另请参阅 ReliabilityRecovery from Remote Service Failure 技术备忘录,了解此解决方案的位置透明度方面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Achieve protected variation as follows: Analyze several commercial tax calculator products (and so forth for the other product categories) and construct common interfaces for the lowest common denominators of functionality. Then use Indirection via the Adapter pattern. That is, create a resource Adapter object that implements the interface and acts as connection and translator to a particular back-end tax calculator. See also the ReliabilityRecovery from Remote Service Failure technical memo for the location transparency aspects of this solution.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        简单。与使用消息服务相比,通信更便宜、更快捷(请参阅替代方案),并且在任何情况下,消息服务都不能用于直接连接到外部信用授权服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Simple. Cheaper, and faster communication than using a messaging service (see alternatives), and in any event a messaging service can't be used to directly connect to the external credit authorization service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        未解决的问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Unresolved Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        最小公分母接口是否会产生不可预见的问题,例如太有限?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Will the lowest common denominator interfaces create an unforeseen problem, such as too limited?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        考虑的替代方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Alternatives Considered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        通过在客户端和税收计算器之间使用消息传递或发布-订阅服务(例如,JMS 实现)和适配器来应用间接。但不能直接与信用授权方一起使用,成本高昂(对于可靠的信用授权方),并且消息传输的可靠性高于实际需要的可靠性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apply indirection by using a messaging or publish-subscribe service (e.g., a JMS implementation) between the client and tax calculator, with adapters. But not directly usable with a credit authorizer, costly (for reliable ones), and more reliability in message delivery than is practically needed.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        关键是,在体系结构级别,通常有新的机制来实现受保护的变体(和其他目标),通常与第三方组件协作,例如使用 Java Messaging Service (JMS) 或 EBJ 服务器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The point is that at the architectural level, there are usually new mechanisms to achieve protected variation (and other goals), often in collaboration with third-party components, such as using a Java Messaging Service (JMS) or EBJ server.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        关注点分离和影响定位

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        架构分析过程中应用的另一个基本原则是实现关注点分离。它也适用于小对象的比例,但在架构分析中表现突出。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Another basic principle applied during architectural analysis is to achieve a separation of concerns. It is also applicable at the scale of small objects, but achieves prominence during architectural analysis.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        横切关注点是指在系统中具有广泛应用或影响的关注点,例如数据持久性或安全性。可以在 NextGen 应用程序中设计持久性支持,以便每个对象(包含应用程序逻辑代码)本身也与数据库通信以保存其数据。这将把对持久性的关注与应用程序逻辑的关注交织在一起,在类的源代码中也是如此。内聚力下降,耦合上升。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Cross-cutting concerns are those with a wide application or influence in the system, such as data persistence or security. One could design persistence support in the NextGen application such that each object (that contained application logic code) itself also communicated with a database to save its data. This would weave the concern of persistence in with the concern of application logic, in the source code of the classesso too with security. Cohesion drops and coupling rises.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        相比之下,关注点分离的设计将持久化支持和安全支持分解为单独的“事物”(这种分离的机制非常不同)。具有应用程序逻辑的对象仅具有应用程序逻辑,而不是持久性或安全逻辑。同样,持久性子系统侧重于持久性的关注点,而不是安全性。安全子系统不执行持久性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In contrast, designing for a separation of concerns factors out persistence support and security support into separate "things" (there are very different mechanisms for this separation). An object with application logic just has application logic, not persistence or security logic. Similarly, a persistence subsystem focuses on the concern of persistence, not security. A security subsystem doesn't do persistence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        关注点分离是在架构级别考虑低耦合和高内聚的一种大规模方式。它也适用于小比例对象,因为不存在它会导致具有多个责任区域的不连续对象。但这尤其是一个架构问题,因为关注点很广泛,并且解决方案涉及主要的、基本的设计选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Separation of concerns is a large-scale way of thinking about low coupling and high cohesion at an architectural level. It also applies to small-scale objects, because its absence results in incohesive objects that have multiple areas of responsibility. But it is especially an architectural issue because the concerns are broad, and the solutions involve major, fundamental design choices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有几种大规模技术可以实现关注点分离:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There are several large-scale techniques to achieve a separation of concerns:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 将关注点模块化为单独的组件(例如,子系统)并调用其服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 这是最常见的方法。例如,在 NextGen 系统中,持久性支持可以被分解到一个称为持久性服务的子系统中。通过 Facade,它可以为其他组件提供服务的公共接口。分层体系结构也说明了这种关注点分离。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Modularize the concern into a separate component (for example, subsystem) and invoke its services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • This is the most common approach. For example, in the NextGen system, the persistence support could be factored into a subsystem called the persistence service. Via a facade, it can offer a public interface of services to other components. Layered architectures also illustrate this separation of concerns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 使用装饰器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 这是第二种最常见的方法;首先在 Microsoft Transaction Service 中普及,后来在 EJB 服务器中普及。在这种方法中,关注点(例如安全性)被装饰到其他对象上,该对象包装内部对象并插入服务。在 EJB 术语中,Decorator 称为容器。例如,在 NextGen POS 系统中,可以通过 EJB 容器实现对远程服务(如 HR 系统)的安全控制,该容器在外部 Decorator 中围绕内部对象的应用程序逻辑添加安全检查。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. Use decorators.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • This is the second most common approach; first popularized in the Microsoft Transaction Service, and afterwards with EJB servers. In this approach, the concern (such as security) is decorated onto other objects with a Decorator object that wraps the inner object and interposes the service. The Decorator is called a container in EJB terminology. For example, in the NextGen POS system, security control to remote services such as the HR system can be achieved with an EJB container that adds security checks in the outer Decorator, around the application logic of the inner object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        5. 使用后编译器和面向方面的技术。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 例如,使用 EJB 实体 Bean,可以向 Sale 等类添加持久性支持。一个在属性描述符文件中指定 Sale 类的持久性特征。然后,后编译器(我指的是在“常规”编译器之后执行的另一个编译器)将在修改后的 Sale 类(仅修改字节码)或子类中添加必要的持久性支持。开发人员继续将原始类视为 “干净” 的仅应用程序逻辑类。另一种变体是面向方面的技术,例如 AspectJ (www.aspectj.org),它同样支持以对开发人员透明的方式将横切关注点编织到代码中。这些方法在开发工作中保持了分离的错觉,并在执行之前编织了关注点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        6. Use post-compilers and aspect-oriented technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • For example, with EJB entity beans one can add persistence support to classes such as Sale. One specifies in a property descriptor file the persistence characteristics of the Sale class. Then, a post-compiler (by which I mean another compiler that executes after the "regular" compiler) will add the necessary persistence support in a modified Sale class (modifying just the bytecode) or subclass. The developer continues to see the original class as a "clean" application-logic-only class. Another variation is aspect-oriented technologies such as AspectJ (www.aspectj.org), which similarly support post-compilation weaving in of cross-cutting concerns into the code, in a manner that is transparent to the developer. These approaches maintain the illusion of separation during development work, and weave in the concern before execution.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        建筑模式的推广

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Promotion of Architectural Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对架构模式的探索以及它们如何应用(或误应用)到 NextGen 案例研究中,超出了本介绍性文本的范围。但是,有几点建议:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An exploration of architectural patterns and how they could apply (or misapply) to the NextGen case study is out of scope in this introductory text. However, a few pointers:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在架构级别实现低耦合、受保护变体和关注点分离的最常见机制可能是 Layers 模式,该模式已在上一章中介绍过。这是最常见的分离技术的示例,将关注点模块化为单独的组件或层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Probably the most common mechanism to achieve low coupling, protected variation, and a separation of concerns at the architectural level is the Layers pattern, which has been introduced a previous chapter. This is an example of the most common separation techniquemodularizing concerns into separate components or layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有大量且不断增长的书面架构模式。研究这些是我所知道的学习架构解决方案的最快方法。请参阅推荐读数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There is a large and growing body of written architectural patterns. Studying these is the fastest way I know of to learn architectural solutions. Please see the recommended readings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          33.8. 架构分析中的主题总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          33.8. Summary of Themes in Architectural Analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          首先要注意的主题是 “架构” 关注点与非功能性需求特别相关,包括对应用程序的业务或市场环境的认识。同时,功能需求(例如,处理销售)不能被忽视;它们提供了必须解决这些问题的背景。此外,识别它们的可变性在架构上具有重要意义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The first theme to note is that "architectural" concerns are especially related to non-functional requirements, and include an awareness of the business or market context of the application. At the same time, the functional requirements (for example, processing sales) cannot be ignored; they provide the context within which these concerns must be resolved. Further, identification of their variability is architecturally significant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          第二个主题是架构关注点涉及系统级、大规模和广泛的问题,其解决通常涉及大规模或基本设计决策;例如,选择 ofor even 使用 OFAN Application Server。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A second theme is that architectural concerns involve system-level, large-scale, and broad problems whose resolution usually involves large-scale or fundamental design decisions; for example, the choice ofor even use ofan application server.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构分析的第三个主题是相互依赖关系和权衡。例如,提高安全性可能会影响性能或可用性,而大多数选择都会影响成本。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A third theme in architectural analysis is interdependencies and trade-offs. For example, improved security may affect performance or usability, and most choices affect cost.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构分析的第四个主题是替代解决方案的生成和评估。熟练的架构师可以提供涉及构建新软件的设计解决方案,还可以提出使用商业或公开可用的软件和硬件的解决方案(或部分解决方案)。例如,NextGen POS 远程服务器中的恢复可以通过设计和编程“看门狗”进程来实现,或者可能通过某些操作系统和硬件组件提供的群集、复制和故障转移服务来实现。优秀的架构师了解第三方硬件和软件产品。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A fourth theme in architecture analysis is the generation and evaluation of alternative solutions. A skilled architect can offer design solutions that involve building new software, and also suggest solutions (or partial solutions) using commercial or publicly available software and hardware. For example, recovery in a remote server of the NextGen POS can be achieved through designing and programming "watchdog" processes, or perhaps through clustering, replication, and fail-over services offered by some operating system and hardware components. Good architects know third-party hardware and software products.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构关注点的开篇定义为如何思考架构主题提供了框架:识别具有大规模或系统级影响的问题,并解决它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The opening definition of architectural concerns provides the framework for how to think about the subject of architecture: identifying the issues with large-scale or system-level implications, and resolving them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构分析涉及在功能需求上下文中识别和解决系统的非功能需求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Architectural analysis is concerned with the identification and resolution of the system's non-functional requirements in the context of the functional requirements.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            33.9. 流程:UP 中的迭代架构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            33.9. Process: Iterative Architecture in the UP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            UP 是一种以架构为中心的迭代和进化方法。这并不意味着在开发之前尝试完全识别所有架构需求,也不意味着在编程和测试之前尝试完全设计“正确”的架构。相反,这意味着早期迭代侧重于对架构上重要的关注点(例如安全性)进行编程和测试,以及使用、证明、开发和稳定关键架构元素(子系统、接口、框架等)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The UP is an architecture-centric iterative and evolutionary method. This does not mean a waterfall attempt to fully identify all architectural requirements before development, nor an attempt to fully design the "correct" architecture before program and test. Rather, it means that early iterations focus on programming and testing architecturally significant concerns (such as security) and using, proving, developing and stabilizing the key architectural elements (subsystems, interfaces, frameworks, and so on).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在 UP 中,架构通过早期开发和测试来发展和稳定,以架构为重点,而不是通过纸面上的猜测或“PowerPoint 架构”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the UP, the architecture evolves and stabilizes through early development and test with an architecture-focus, not through speculation on paper, or "PowerPoint Architecture."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在 UP 中,架构因素或需求记录在补充规范中,解决这些要求的架构决策记录在软件架构文档 (SAD) 中。因为 UP 不是瀑布,所以 SAD 不是在编程之前完全创建的,而是在编程后代码稳定下来创建的。然后,SAD 将实际系统记录下来,作为其他人的学习辅助工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the UP, the architectural factorsor requirementsare recorded in the Supplementary Specification, and the architectural decisions that resolve them are recorded in the Software Architecture Document (SAD). Because the UP is not the waterfall, the SAD is not fully created before programming, but rather, after programmingonce the code has stabilized. Then, the SAD documents the actual system as a learning aid for others.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            架构分析在初期阶段就开始了,是细化阶段的重点;它是软件开发中一项高度优先且非常有影响力的活动。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural analysis starts early, during the inception phase, and is a focus of the elaboration phase; it is a high-priority and very influential activity in software development.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            UP 工件中的架构信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural Information in the UP Artifacts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 架构因子 (例如,在因子表中) 记录在补充规范中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • The architectural factors (for example, in a factor table) are recorded in the Supplementary Specification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 架构决策记录在 SAD 中。这包括建筑视图的技术备忘录和描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • The architectural decisions are recorded in the SAD. This includes the technical memos and descriptions of the architectural views.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            阶段

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Phases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            初始如果不清楚在技术上是否可能满足架构上重要的要求,团队可以实施架构概念验证 (POC) 来确定可行性。在 UP 中,它的创建和评估称为 Architectural Synthesis。这与针对孤立技术问题的普通小型 POC 编程实验不同。架构 POC 略微涵盖了许多架构上重要的要求,以评估它们的组合可行性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Inception If it is unclear whether it is technically possible to satisfy the architecturally significant requirements, the team may implement an architectural proof-of-concept (POC) to determine feasibility. In the UP, its creation and assessment is called Architectural Synthesis. This is distinct from plain old small POC programming experiments for isolated technical questions. An architectural POC lightly covers many of the architecturally significant requirements to assess their combined feasibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            阐述此阶段的一个主要目标是实现核心风险架构元素,因此大多数架构分析都是在细化过程中完成的。通常预计大部分因子表、技术备忘录和 SAD 内容可以在阐述结束时完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Elaboration A major goal of this phase is to implement the core risky architectural elements, thus most architectural analysis is completed during elaboration. It is normally expected that the majority of factor table, technical memo, and SAD content can be completed by the end of elaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            过渡尽管理想情况下,架构上重要的因素和决策在过渡之前很久就已经解决了,但 SAD 需要在此阶段结束时进行审查和可能的修订,以确保它准确描述最终部署的系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Transition Although ideally the architecturally significant factors and decisions were resolved long before transition, the SAD will need a review and possible revision at the end of this phase to ensure it accurately describes the final deployed system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            后续的进化周期在设计新版本之前,通常会重新审视架构因素和决策。例如,版本 1.0 中决定创建一个远程税务计算器服务,而不是在每个 POS 节点上复制一个服务,这可能是出于成本(以避免多个许可证)。但也许将来税收计算器的成本会降低,因此,出于容错或性能原因,架构会更改为使用多个本地税收计算器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Subsequent evolution cycles Before the design of new versions, it is common to revisit architectural factors and decisions. For example, the decision in version 1.0 to create a single remote tax calculator service, rather than one duplicated on each POS node, could have been motivated by cost (to avoid multiple licenses). But perhaps in the future the cost of tax calculators is reduced, and thus, for fault tolerance or performance reasons, the architecture is changed to use multiple local tax calculators.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              33.10. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              33.10. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              与架构相关的模式和一般的软件架构建议越来越多。建议:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              There is a growing body of architecture-related patterns, and general software architecture advice. Suggestions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 超越软件架构 [Hohman03]。这个有用的指南由经验丰富的架构师和产品经理编写,它强调了面向业务的架构。Hohman 分享了他很少涉及的重要问题的经验,例如业务模型、许可和升级对软件架构的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Beyond Software Architecture [Hohman03]. This useful guide, from someone experienced as both architect and product manager, brings a business-oriented emphasis to architecture. Hohman shares his experience with important issues seldom covered, such as the impact of the business model, licensing, and upgrades on the software architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 企业应用程序体系结构的模式 [Fowler02]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Patterns of Enterprise Application Architecture [Fowler02].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 软件体系结构实践 [BCK98]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Software Architecture in Practice [BCK98].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 面向模式的软件架构,两卷。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Pattern-Oriented Software Architecture, both volumes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 程序设计的模式语言,所有卷。每个卷都有一个关于架构相关模式的部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Pattern Languages of Program Design, all volumes. Each volume has a section on architecture-related patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                第 34 章.逻辑架构优化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Chapter 34. Logical Architecture Refinement

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                酒精和肺结石不能混在一起......不要喝酒和衍生。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                匿名

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Alcohol and calculus don't mix… Don't drink and derive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                anonymous

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 探索逻辑体系结构和 Layers 模式中的更多问题,包括层间协作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Explore more issues in logical architecture and the Layers pattern, including inter-layer collaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 介绍此案例研究迭代的逻辑架构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Present the logical architecture for this iteration of the case studies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 在建筑图层的上下文中应用 Facade、Observer 和 Controller 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Apply the Facade, Observer, and Controller patterns in the context of architectural layers.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  逻辑体系结构和 Layers 模式从 第 197 页开始介绍。本章更深入地探讨了与分层架构相关的一些中间主题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Logical architecture and the Layers pattern was introduced starting on p. 197. This chapter dives a bit deeperlooking at some intermediate topics related to layered architectures.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    34.1. 示例:NextGen Logical Architecture

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    34.1. Example: NextGen Logical Architecture



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 34.1 说明了 NextGen 应用程序迭代的部分逻辑分层架构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Figure 34.1 illustrates a partial logical layered architecture for this iteration of NextGen application.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 34.1.NextGen 应用程序中层的部分逻辑视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,此设计迭代缺少 Application 层;正如后面所讨论的,这并不总是必要的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note the absence of an Application layer for this iteration of the design; as discussed later, it is not always necessary.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    由于这是迭代开发,因此创建从简单开始并随着细化阶段的迭代而演变的层设计是正常的。这个阶段的一个目标是在细化迭代结束时建立(设计和实现)核心架构,但这并不意味着在开始编程之前做一个大型的前期推测性架构设计。相反,在早期迭代中设计了一个试探性的逻辑架构,并在细化阶段逐步发展。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Since this is iterative development, it is normal to create a design of layers that starts simple, and evolves over the iterations of the elaboration phase. One goal of this phase is to have the core architecture established (designed and implemented) by the end of the iterations in elaboration, but this does not mean doing a large up-front speculative architectural design before starting to program. Rather, a tentative logical architecture is designed in the early iterations, and it evolves incrementally through the elaboration phase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,此封装图中仅存在几种样本类型;这不仅是由于本书排版的页面空间有限,而且是架构视图图的标志性品质它只显示了一些值得注意的元素,以便简洁地传达架构重要方面的大思想。UP 架构视图文档中的想法是对读者说,“我选择了这一小组指导性元素来传达大想法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Observe that just a few sample types are present in this package diagram; this is not only motivated by limited page space in formatting this book, but is a signature quality of an architectural view diagramit only shows a few noteworthy elements in order to concisely convey the big ideas of the architecturally significant aspects. The idea in a UP architectural view document is to say to the reader, "I've chosen this small set of instructive elements to convey the big ideas."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    对图 34.1 的注释:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Comments on Figure 34.1:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 这些包中还有其他类型;仅显示少数几个以指示值得注意的方面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • There are other types in these packages; only a few are shown to indicate noteworthy aspects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 基础图层未显示在此视图中;架构师(我)决定不添加有趣的信息,尽管开发团队肯定会添加一些 Foundation 类,例如更高级的 String 操作实用程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • The Foundation layer was not shown in this view; the architect (me) decided it did not add interesting information, even though the development team will certainly be adding some Foundation classes, such as more advanced String manipulation utilities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 目前,未使用单独的 Application 层。Application 层中控制或会话对象的职责由 Register 对象处理。随着行为复杂性的增加,架构师将在以后的迭代中添加一个 Application 层,并引入替代客户端接口(比如 Web 浏览器和无线网络手持 PDA)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • For now, a separate Application layer is not used. The responsibilities of control or session objects in the Application layer are handled by the Register object. The architect will add an Application layer in a later iteration as the behavior grows in complexity, and alternative client interfaces are introduced (such as a Web browser and wireless networked handheld PDA).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    层间和封装间耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Inter-Layer and Inter-Package Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    为了帮助人们理解 NextGen 逻辑架构,在逻辑视图中包含一个图表也很有帮助,该图表说明了层和包之间值得注意的耦合。图 34.2 说明了部分示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To help someone understand the NextGen logical architecture, it's also informative to include a diagram in the logical view that illustrates noteworthy coupling between the layers and packages. A partial example is illustrated in Figure 34.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 34.2.封装之间的部分耦合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    应用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Applying UML:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 请注意,依赖关系行可用于传达包之间的耦合或包中的类型。当 communicator 不关心更具体地说明确切的依赖关系(属性可见性、子类化等),而只想突出一般依赖关系时,简单的依赖关系行是非常好的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Observe that dependency lines can be used to communicate coupling between packages or types in packages. Plain dependency lines are excellent when the communicator does not care to be more specific on the exact dependency (attribute visibility, subclassing, …), but just wants to highlight general dependencies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 另请注意,使用从包而不是特定类型发出的依赖关系行,例如从 Sales 包到 POSRuleEngineFacade 类,以及从 Domain 包到 Log4J 包。当特定的依赖类型不感兴趣,或者通信者想要建议包的许多元素可以共享该依赖时,这很有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Note also the use of a dependency line emitting from a package rather than a particular type, such as from the Sales package to POSRuleEngineFacade class, and the Domain package to the Log4J package. This is useful when either the specific dependent type is not interesting, or the communicator wants to suggest that many elements of the package may share that dependency.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    包图的另一个常见用途是隐藏特定类型,并专注于说明包-包耦合,如图 34.3 的部分图所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Another common use of a package diagram is to hide the specific types, and focus on illustrating the package-package coupling, as in the partial diagram of Figure 34.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 34.3.部分封装耦合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    事实上,图 34.3 说明了 UMLa 包图中最常见的逻辑架构图样式,它可能显示了 5 到 20 个主要包及其依赖关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In fact, Figure 34.3 illustrates probably the most common style of logical architecture diagram in the UMLa package diagram that shows between perhaps 5 to 20 major packages, and their dependencies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    层间和包间交互场景

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Inter-Layer and Inter-Package Interaction Scenarios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    包图显示静态信息。为了帮助人们理解 NextGen 逻辑架构中的动态,包括一个跨层对象如何连接和通信的图表也很有用。因此,交互图很有帮助。本着隐藏无趣细节并强调架构师想要传达的内容的 “架构视图” 的精神,架构逻辑视图中的交互图侧重于跨层和包边界的协作。因此,一组说明体系结构重要场景的交互图(从某种意义上说,它们说明了设计中大规模或大想法的许多方面)是有用的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Package diagrams show static information. To help someone understand the dynamics in the NextGen logical architecture, it's also useful to include a diagram of how objects across the layers connect and communicate. Thus, an interaction diagram is helpful. In the spirit of an "architectural view" which hides uninteresting details, and emphasizes what the architect wants to convey, an interaction diagram in the logical view of the architecture focuses on the collaborations as they cross layer and package boundaries. A set of interaction diagrams that illustrate architecturally significant scenarios (in the sense that they illustrate many aspects of the large-scale or big ideas in the design) is thus useful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    例如,图 34.4 说明了 Process Sale 场景的一部分,该场景强调了跨层和包的连接点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For example, Figure 34.4 illustrates part of a Process Sale scenario that emphasizes the connection points across the layers and packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 34.4.强调跨界连接的体系结构上重要的交互图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    应用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Applying UML:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 可以选择通过使用 UML 路径名称表达式 <PackageName>::<TypeName> 限定类型来显示类型的包。例如,Domain::Sales::Register。可以利用这一点向读者突出显示交互图中的包间和层间连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • The package of a type can optionally be shown by qualifying the type with the UML path name expression <PackageName>::<TypeName>. For example, Domain::Sales::Register. This can be exploited to highlight to the reader the inter-package and inter-layer connections in the interaction diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 还要注意 “subsystem” 刻板印象的使用。在 UML 中,子系统是具有行为和接口的离散实体。子系统可以建模为一种特殊类型的包,或者此处显示为对象,这在想要显示子系统(或系统)间的协作时很有用。在 UML 中,整个系统也是一个 “子系统”(根系统),因此也可以在交互图(例如 SSD)中显示为对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Note also the use of the «subsystem» stereotype. In the UML, a subsystem is a discrete entity that has behavior and interfaces. A subsystem can be modeled as a special kind of package, oras shown hereas an object, which is useful when one wants to show inter-subsystem (or system) collaborations. In the UML, the entire system is also a "subsystem" (the root one), and thus can also be shown as an object in interaction diagrams (such as an SSD).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 请注意,使用右上角的 '1' 来表示单例,并建议使用 GoF 单例模式进行访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Note the use of the '1' in the top right corner to indicate a singleton, and suggest access using the GoF Singleton pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,该图忽略了显示某些消息,例如某些 Sale 协作,以突出显示在体系结构上具有重要意义的交互。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Observe that the diagram ignores showing some messages, such as certain Sale collaborations, in order to highlight architecturally significant interactions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      34.2. 使用 Layers 模式的协作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      34.2. Collaborations with the Layers Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      架构级别的两个设计决策是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Two design decisions at an architectural level are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. 主要部分有哪些?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. What are the big parts?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. 它们是如何连接的?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4. How are they connected?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      架构 Layers 模式指导定义主要部分,而 Facade、Controller 和 Observer 等微架构设计模式通常用于设计层和包之间的连接。本节介绍层和包之间的连接和通信模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Whereas the architectural Layers pattern guides defining the big parts, micro-architectural design patterns such as Facade, Controller, and Observer are commonly used for the design of the connections between layers and packages. This section examines patterns in connection and communication between layers and packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      简单包与子系统

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Simple Packages versus Subsystems

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      一些包或层不仅仅是概念性的事物组,而是具有行为和接口的真正子系统。对比:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Some packages or layers are not just conceptual groups of things, but are true subsystems with behavior and interfaces. To contrast:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Pricing package 不是一个子系统;它只是对定价中使用的工厂和策略进行分组。对于 Foundation 包(如 java.util)也是如此。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The Pricing package is not a subsystem; it simply groups the factory and strategies used in pricing. Likewise with Foundation packages such as java.util.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 另一方面,Persistence、POSRuleEngineJess 包是子系统。它们是独立的引擎,具有协同工作的有凝聚力的职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • On the other hand, the Persistence, POSRuleEngine, and Jess packages are subsystems. They are discrete engines with cohesive responsibilities that do work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 UML 中,可以使用构造型来标识子系统,如图 34.5 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In the UML, a subsystem can be identified with a stereotype, as in Figure 34.5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.5.子系统刻板印象。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      外观

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Facade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对于表示子系统的包,最常见的访问模式是 Facade,这是一种 GoF 设计模式。也就是说,公共 Facade 对象定义子系统的服务,客户端与 Facade 协作,而不是与内部子系统组件协作。POSRuleEngineFacadePersistenceFacade 用于访问规则引擎和持久性子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For packages that represent subsystems, the most common pattern of access is Facade, a GoF design pattern. That is, a public facade object defines the services for the subsystem, and clients collaborate with the facade, not internal subsystem components. This is true of the POSRuleEngineFacade and the PersistenceFacade for access to the rules engine and persistence subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      门面通常不应公开许多低级操作。相反,希望 Facade 公开少量的高级操作粗粒度服务。当 Facade 确实暴露了许多低级操作时,它往往会变得不连贯。此外,如果 Facade 将要或可能成为分布式或远程对象(比如 EJB 会话 Bean 或 RMI 服务器对象),那么细粒度的服务会导致远程通信性能问题。在分布式系统中,大量小的远程调用是性能瓶颈。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The facade should not normally expose many low-level operations. Rather, it is desirable for the facade to expose a small number of high-level operationsthe coarse-grained services. When a facade does expose many low-level operations, it tends to become incohesive. Furthermore, if the facade will be, or might become, a distributed or remote object (such as an EJB session bean, or RMI server object), fine-grained services lead to remote communication performance problemslots of little remote calls are a performance bottleneck in distributed systems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      此外,立面通常不执行其自身的工作。相反,它是执行工作的基础子系统对象的整合器或中介器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Also, a facade does not normally do its own work. Rather, it is consolidator or mediator to the underlying subsystem objects, which do the work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,POSRuleEngineFacade 是 POS 应用程序的规则引擎的包装器和单一访问点。其他包看不到此子系统的实现,因为它隐藏在 Facade 后面。假设(这只是众多实现之一)POS 规则引擎子系统是通过与 Jess 规则引擎协作实现的。Jess 是一个公开许多细粒度操作的子系统(这在非常通用的第三方子系统中很常见)。但是 POSRuleEngineFacade 不会在其界面中公开低级 Jess 操作。相反,它仅提供一些高级操作,例如 isInvalid(lineItem, sale)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, the POSRuleEngineFacade is the wrapper and single point of access into the rules engine for the POS application. Other packages do not see the implementation of this subsystem, as it is hidden behind the facade. Suppose (this is just one of many implementations) that the POS rules engine subsystem is implemented by collaborating with the Jess rules engine. Jess is a subsystem that exposes many fine-grained operations (this is common for very general, third-party subsystems). But the POSRuleEngineFacade does not expose the low-level Jess operations in its interface. Rather, it provides only a few high-level operation such as isInvalid(lineItem, sale).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果应用程序只有 “少量” 的系统操作,那么 Application 层或 Domain 层通常只向上层公开一个对象。另一方面,包含多个子系统的技术服务层将每个子系统的至少一个立面(或多个公共对象,如果未使用立面)公开给上层。参见图 34.6

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If the application has only a "small" number of system operations, then it is common for the Application or Domain layer to expose only one object to an upper layer. On the other hand, the Technical Services layer, which contains several subsystems, exposes at least one facade (or several public objects, if facades aren't used) for each subsystem to upper layers. See Figure 34.6.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.6.暴露于上层的接口数。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      会话 Facades 和应用层

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Session Facades and the Application Layer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.6 相反,当应用程序有许多系统操作并支持许多用例时,在 UI 层和域层之间有多个对象中介是很常见的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In contrast to Figure 34.6, when an application has many system operations and supports many use cases, it is common to have more than one object mediating between the UI and Domain layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在当前版本的 NextGen 系统中,有一个简单的设计,即单个 Register 对象充当 Domain 层的 Facade(凭借 GRASP 控制器模式)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In the current version of the NextGen system, there is a simple design of a single Register object acting as the facade onto the Domain layer (by virtue of the GRASP controller pattern).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      但是,随着系统发展到可以处理许多使用案例和系统操作,引入对象应用程序层的情况并不少见,这些对象维护使用案例操作的会话状态,其中每个会话实例表示与一个客户端的会话。这些称为会话 Facades,它们的使用是 GRASP Controller 模式的另一个建议,例如在模式的用例 session Facade Controller 变体中。参见图 34.7 了解 NextGen 架构如何随着 Application 层和 session Facades 的发展而发展。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      However, as the system grows to handle many use cases and system operations, it is not uncommon to introduce an Application layer of objects that maintain session state for the operations of a use case, where each session instance represents a session with one client. These are called Session Facades, and their use is another recommendation of the GRASP Controller pattern, such as in the use-case session facade controller variant of the pattern. See Figure 34.7 for an example of how the NextGen architecture may evolve with an Application layer and session facades.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.7.会话 Facades 和 Application Layer。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GRASP Controller 模式描述了客户端处理程序(或控制器,因为它们被称为控制器)中对从 UI 层发出的系统操作请求的常见选择。图 34.8 说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The GRASP Controller pattern describes common choices in client-side handlers (or controllers, as they've been called) for system operation requests emitting from the UI layer. Figure 34.8 illustrates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.8.Controller 选项。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      系统操作和层

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      System Operations and Layers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SSD 说明了系统操作,在图表中隐藏了 UI 对象。图 34.9 中在系统上调用的系统操作是 actor 通过 UI 层生成的请求,这些请求被发送到 Application 或 Domain 层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The SSDs illustrate the system operations, hiding UI objects from the diagram. The system operations being invoked on the system in Figure 34.9 are requests being generated by an actor via the UI layer, onto the Application or Domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.9.SSD 和层中的系统操作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      与 Observer 的向上合作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Upward Collaboration with Observer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Facade 模式通常用于从较高层到较低层的 “向下” 协作,或用于访问同一层的另一个子系统中的服务。当较低的 Application 或 Domain 层需要与 UI 层向上通信时,通常是通过 Observer 模式。也就是说,较高 UI 层中的 UI 对象实现 PropertyListenerAlarmListener 等接口,并且是来自较低层中的对象的事件(例如属性或警报事件)的订阅者或侦听器。下层对象直接向上层 UI 对象发送消息,但耦合仅与被视为实现接口的对象(如 PropertyListener)相关联,而不是被视为特定的 GUI 窗口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Facade pattern is commonly used for "downward" collaboration from a higher to a lower layer, or for access to services in another subsystem of the same layer. When the lower Application or Domain layer needs to communicate upward with the UI layer, it is usually via the Observer pattern. That is, UI objects in the higher UI layer implement an interface such as PropertyListener or AlarmListener, and are subscribers or listeners to events (such as property or alarm events) coming from objects in the lower layers. The lower layer objects are directly sending messages to the upper layer UI objects, but the coupling is only to the objects viewed as things that implement an interface, such as PropertyListener, not viewed as specific GUI windows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当引入 Observer 模式时,对此进行了检查。图 34.10 总结了与 layers 相关的概念。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This was examined when the Observer pattern was introduced. Figure 34.10 summarizes the idea in relation to layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 34.10.Observer 用于与 UI 层的 “向上” 通信。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      松弛分层耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Relaxed Layered Coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      大多数分层架构中的层在有限意义上基于 OSI 7 层模型的网络协议不同。在协议模型中,有严格的限制,即第 N 层的元素只能访问直接的较低层 N-1 的服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The layers in most layered architectures are not coupled in the same limited sense as a network protocol based on the OSI 7-Layer Model. In the protocol model, there is strict restriction that elements of layer N only access the services of the immediate lower layer N-1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这在信息系统架构中很少遵循。相反,该标准是“松散分层”或“透明分层”架构 [BMRSS96],其中层的元素与其他几个层协作或耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is rarely followed in information system architectures. Rather, the standard is a "relaxed layered" or "transparent layered" architecture [BMRSS96], in which elements of a layer collaborate with or are coupled to several other layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      关于层间典型耦合的评论:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Comments on typical coupling between layers:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 所有更高层都依赖于 Technical Services 和 Foundations 层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 例如,在 Java 中,所有层都依赖于 java.util 包元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • All higher layers have dependencies on the Technical Services and Foundations layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • For example, in Java all layers depend on java.util package elements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 它主要是依赖于 Business Infrastructure 层的 Domain 层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • It is primarily the Domain layer that has dependency on the Business Infrastructure layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • UI 层在应用程序层上进行调用,应用程序层在域层上进行服务调用;UI 层不会调用 Domain,除非没有 Application 层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • The UI layer makes calls on the Application layer, which makes service calls on the Domain layer; the UI layer does not call on the Domain, unless there is no Application layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 如果它是一个单进程的“桌面”应用程序,则域层中的软件对象可以直接看到 UI、应用程序,并在较小程度上看到技术服务,或者在 UI 和应用程序之间传递。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 例如,假设 NextGen POS 系统是这种类型的,则 SalePayment 对象可以直接对 GUI UI 层可见,并且还可以传递到技术服务层的 Persistence 子系统中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • If it is a single-process "desktop" application, software objects in the Domain layer are directly visible to, or passed between, UI, Application, and to a lesser extent, Technical Services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • For example, assuming the NextGen POS system is of this type, a Sale and a Payment object could be directly visible to the GUI UI Layer, and also passed into the Persistence subsystem in the Technical Services layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 另一方面,如果它是一个分布式系统,那么域层中对象的可序列化副本(也称为数据容器值对象)通常会传递到 UI 层。在这种情况下,域层部署在服务器计算机上,客户端节点获取服务器数据的副本。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • On the other hand, if it is a distributed system, then serializable replicates (also known as data holder or value objects) of objects in the Domain layer are usually passed to a UI layer. In this case, the Domain layer is deployed on a server computer, and client nodes get copies of server data.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      耦合到技术层和基础层不是很危险吗?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      正如 GRASP 受保护变体和低耦合讨论所探讨的那样,问题不在于耦合本身,而在于与不稳定且修复成本高昂的变异和进化点的不必要耦合。花费时间和金钱试图抽象或隐藏不太可能改变的东西是没有道理的,或者即使发生了,改变影响的成本也可以忽略不计。例如,如果构建 Java 技术应用程序,那么隐藏应用程序以阻止对 Java 库的访问有什么价值呢?与库的许多点的高度耦合是一个不太可能的问题,因为它们(相对)稳定且无处不在。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As the GRASP Protected Variations and Low Coupling discussions explored, it is not coupling per se that is a problem, but unnecessary coupling to variation and evolution points that are unstable and expensive to fix. There is very little justification in spending time and money attempting to abstract or hide something that is unlikely to change, or if it did, the change impact cost would be negligible. For example, if building a Java technologies application, what value is there in hiding the application from access to the Java libraries? High coupling into many points of the libraries is an unlikely problem, as they are (relatively) stable and ubiquitous.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        34.3. 其他层模式问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        34.3. Other Layer Pattern Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        除了上面讨论的 Layers 模式的结构和协作问题外,其他问题还包括以下内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In addition to the structural and collaboration issues discussed above for the Layers pattern, other issues include the following.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        体系结构的逻辑视图与流程视图和部署视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Logical versus Process and Deployment Views of the Architecture

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        架构层是架构的逻辑视图,而不是元素到流程和处理节点的部署视图。根据平台的不同,所有层都可以部署在同一个节点上的同一进程中,例如手持 PDA 中的应用程序,或者分布在许多计算机和进程中,用于大规模 Web 应用程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The architectural layers are a logical view of the architecture, not a deployment view of elements to processes and processing nodes. Depending on the platform, all layers could be deployed within the same process on the same node, such as an application within a handheld PDA, or spread across many computers and processes for a large-scale Web application.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        将此逻辑体系结构映射到进程和节点的 UP 部署模型受到软件和硬件平台以及相关应用程序框架选择的强烈影响。例如,J2EE 与 .NET 会影响部署体系结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The UP Deployment Model that maps this logical architecture to processes and nodes is strongly influenced by the choice of software and hardware platform and associated application frameworks. For example, J2EE versus .NET influence the deployment architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        有许多方法可以对这些逻辑层进行切片和切块以进行部署,一般来说,部署体系结构的主题只会被简要介绍,因为它并非平凡,在很大程度上超出了本书的范围,并且取决于对所选软件平台(如 J2EE)的详细讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There are many ways to slice and dice these logical layers for deployment, and in general the subject of deployment architecture will only be lightly introduced, as it is non-trivial, largely outside the scope of the book, and dependent on detailed discussion of the chosen software platform, such as J2EE.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        应用层是可选的吗?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Is the Application Layer Optional?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如果存在,则 Application 层包含负责了解客户端会话状态、在 UI 层和域层之间进行调解以及控制工作流的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        If present, the Application layer contains objects responsible for knowing the session state of clients, mediating between the UI and Domain layers, and controlling the flow of work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例如,可以通过控制窗口或网页的顺序来组织流。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The flow may be organized by controlling the order of windows or web pages, for example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        就 GRASP 模式而言,GRASP 控制器对象(例如用例 Facade 控制器)是该层的一部分。在分布式系统中,诸如 EJB 会话 Bean(以及一般的有状态会话对象)之类的组件是此层的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In terms of the GRASP patterns, GRASP Controller objects such as a use case facade controller are part of this layer. In distributed systems, components such as EJB session beans (and stateful session objects in general) are part of this layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在某些应用程序中,此层不是必需的。当满足以下一项或多项条件时,它很有用(这不是一个详尽的列表):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In some applications, this layer is not required. It is useful (this is not an exhaustive list) when one or more of the following is true:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 系统将使用多个用户界面(例如,Web 页和 Swing GUI)。应用程序层对象可以充当适配器,根据不同 UI 的需要收集和整合数据,也可以充当包装和隐藏对域层的访问的 Facades。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Multiple user interfaces (for example, web pages and a Swing GUI) will be used for the system. The Application layer objects can act as Adapters that collect and consolidate the data as needed for different UIs, and as Facades that wrap and hide access to the Domain layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 它是一个分布式系统,域层与 UI 层位于不同的节点上,并由多个客户端共享。通常需要跟踪会话状态,而 Application layer 对象是承担此职责的有用选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • It is a distributed system and the Domain layer is on a different node than the UI layer, and shared by multiple clients. It is usually necessary to keep track of session state, and Application layer objects are a useful choice for this responsibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 域层不能或不应该维护会话状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The Domain Layer cannot or should not maintain session state.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 根据必须显示的窗口或 Web 页的受控顺序,有一个定义的工作流。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • There is a defined workflow in terms of the controlled order of windows or Web pages that must be presented.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        不同层中的模糊集成员身份

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Fuzzy Set Membership in Different Layers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        某些元素强烈地属于一个层;Math 类是 Foundation 层的一部分。但是,特别是在 Technical Services 和 Foundation 层以及 Domain 和 Business Infrastructure 之间,一些元素更难分类,因为这些层之间的区别大致是 “high” 与 “low” 或 “specific” 与 “general”,它们是模糊的术语。这是正常的,并且很少需要决定一个明确的分类开发团队可能会将一个元素大致视为一个组,大致是技术服务和/或基础层的一部分,广义上称为基础设施层。[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Some elements are strongly a member of one layer; a Math class is part of the Foundation layer. However, especially between the Technical Services and Foundation layers, and Domain and Business Infrastructure, some elements are harder to classify, because the differentiation between these layers is, roughly, "high" versus "low," or "specific" versus "general." which are fuzzy set terms. This is normal, and it is seldom necessary to decide upon a definitive categorizationthe development team may consider an element roughly part of the Technical Services and/or Foundations layer considered as a group, broadly called the Infrastructure layer.[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] 请注意,层没有完善的命名约定,架构文献中的名称过载和矛盾很常见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] Note that there are not well-established naming conventions for layers, and name overloading and contradiction in the architecture literature is common.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 假设这是一个 Java 技术项目,并且选择了开源日志框架 Log4J(Jakarta 项目的一部分)。日志记录是技术服务层还是基础层的一部分?Log4J 是一个低级、小型的通用框架。它适度地同时是 Technical Services 和 Foundations 模糊集的成员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Suppose this is a Java technologies project, and the open source logging framework Log4J (part of the Jakarta project) has been chosen. Is logging part of the Technical Service or Foundation layer? Log4J is a low-level, small, general framework. It is moderately a member of both the Technical Services and the Foundations fuzzy sets.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 假设这是一个 Web 应用程序,并且已经选择了用于 Web 应用程序的 Jakarta Struts 框架。Struts 是一个相对高级、大型、特定的技术框架。可以说,它很强地是技术服务组的成员,而弱地是基金会组的成员。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Suppose this is a Web application, and the Jakarta Struts framework for web applications has been chosen. Struts is a relatively high-level, large, specific technical framework. It is arguably strongly a member of the Technical Services set, and weakly a member of the Foundation set.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        但是,一个人的高级技术服务就是另一个人的基础......

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        But, one person's High-level Technical Service is another's Foundation…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        最后,软件平台提供的库并不代表低级 Foundation 服务。例如,在 .NET 和 J2SE+J2EE 中,服务都包含相对高级的功能,如命名和目录服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Finally, it is not the case that the libraries provided by a software platform only represent low-level Foundation services. For example, in both .NET and J2SE+J2EE, services include relatively high-level functions such as naming and directory services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        蛋鸡的禁忌症和责任

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Contraindications and Liabilities for Layers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 在某些情况下,添加层会带来性能问题。例如,在高性能图形密集型游戏中,在直接访问显卡组件的基础上添加抽象层和间接层可能会带来性能问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • In some contexts, adding layers introduces performance problems. For example, in a high-performance graphics-intensive game, adding layers of abstraction and indirection on top of direct access to graphics card components may introduce performance problems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Layers 模式是几个核心架构模式之一;它并不适用于所有问题。例如,备用项是 Pipes and Filters [BMRSS96]。当应用程序的主题涉及通过一系列转换(如图像转换)处理某些内容,并且转换的顺序是可变的时,这非常有用。然而,即使在最高级别的架构模式是管道和过滤器的情况下,也可以使用图层设计单个管道或过滤器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The Layers pattern is one of several core architectural patterns; it is not applicable to every problem. For example, an alternate is Pipes and Filters [BMRSS96]. This is useful when the main theme of the application involves processing something through a series transformations, such as image transformations, and the ordering of the transformations is changeable. Yet even in the case when the highest level architectural pattern is Pipes and Filters, individual pipes or filters can be design, with Layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        已知用途

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Known Uses

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        大量现代面向对象的系统(从桌面应用程序到分布式 J2EE Web 系统)都是使用 Layer 开发的;找到一个不是的可能比找到一个更难。追溯历史:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A vast number of modern object-oriented systems (from desktop applications to distributed J2EE Web systems) are developed with Layers; it might be harder to find one that is not, than is. Going farther back in history:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        虚拟机和操作系统

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        从 1960 年代开始,操作系统架构师提倡根据明确定义的层来设计操作系统,其中“较低”层封装对物理资源的访问并提供进程和 I/O 服务,而较高层则调用这些服务。其中包括 Multics [CV65] 和 THE 系统 [Dijkstra68]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Starting in the 1960s, operating system architects advocated the design of operating systems in terms of clearly defined layers, where the "lower" layers encapsulated access to the physical resources and provided process and I/O services, and higher layers called on these services. These included Multics [CV65] and the THE system [Dijkstra68].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        早在 1950 年代,研究人员提出了具有字节码通用机器语言的虚拟机 (VM) 的想法(例如,UNCOL [Conway1958]),这样应用程序就可以在架构的更高层编写(并且无需跨不同平台重新编译即可执行),在虚拟机层之上,而虚拟机层又将位于操作系统和机器资源之上。Alan Kay 在他具有里程碑意义的 Flex 面向对象个人计算机系统 [Kay68] 中应用了 VM 分层架构,后来(1972 年)由 Kay 和 Dan Ingalls 应用于有影响力的 Smalltalk 虚拟机 [GK76],GK76 是较新的 VM(如 Java 虚拟机)的鼻祖。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Earlier stillin the 1950sresearchers suggested the idea of a virtual machine (VM) with a bytecode universal machine language (for example, UNCOL [Conway1958]), so that applications could be written at higher layers in the architecture (and executed without recompilation across different platforms), on top of the virtual machine layer, which in turn would sit on top of the operating system and machine resources. A VM layered architecture was applied by Alan Kay in his landmark Flex object-oriented personal computer system [Kay68] and later (1972) by Kay and Dan Ingalls in the influential Smalltalk virtual machine [GK76]the progenitor of more recent VMs such as the Java Virtual Machine.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        信息系统:经典的三层架构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对信息系统分层架构(包括用户界面和数据持久存储)的早期有影响力的描述被称为三层架构(图 34.11),在 1970 年代的 [TK78] 中进行了描述。直到 1990 年代中期,该短语才流行起来,部分原因是它在 [Gartner95] 中被推广为与广泛使用两层架构相关的问题的解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An early influential description of a layered architecture for information systems that included a user interface and persistent storage of data was known as a three-tier architecture (Figure 34.11), described in the 1970s in [TK78]. The phrase did not achieve popularity until the mid 1990s, in part due to its promotion in [Gartner95] as a solution to problems associated with the widespread use of two-tier architectures.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 34.11.三层体系结构的经典视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        原来的术语现在已经不那么常见了,但其动机仍然相关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The original term is now less common, but its motivation is still relevant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        三层体系结构中垂直层的经典描述是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A classic description of the vertical tiers in a three-tier architecture is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 界面窗口、报表等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Interface windows, reports, and so on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 控制流程的 Application Logic 任务和规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. Application Logic tasks and rules that govern the process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        5. 存储持久化存储机制。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        6. Storage persistent storage mechanism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        三层架构的唯一品质是将应用程序逻辑分离到一个不同的软件逻辑中间层。接口层相对没有应用程序处理;窗口或网页将任务请求转发到中间层。中间层与后端存储层通信。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The singular quality of a three-tier architecture is the separation of the application logic into a distinct logical middle tier of software. The interface tier is relatively free of application processing; windows or Web pages forward task requests to the middle tier. The middle tier communicates with the back-end storage layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        存在一些误解,即原始描述暗示或需要在三台计算机上进行物理部署,但预期的描述是纯粹合乎逻辑的;计算节点的层分配可能从 1 到 3 不等。参见图 34.12

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There was some misunderstanding that the original description implied or required a physical deployment on three computers, but the intended description was purely logical; the allocation of the tiers to compute nodes could vary from one to three. See Figure 34.12.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 34.12.部署在两个物理体系结构中的三层逻辑划分。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Gartner Group 的三层架构与两层设计形成鲜明对比,例如,应用程序逻辑放置在窗口定义中,窗口定义直接读取和写入数据库;没有分隔应用程序逻辑的中间层。随着 Visual Basic 和 PowerBuilder 等工具的兴起,两层客户端-服务器体系结构变得特别流行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The three-tier architecture was contrasted by the Gartner Group with a two-tier design, in which, for example, application logic is placed within window definitions, which read and write directly to a database; there is no middle tier that separates out the application logic. Two-tier client-server architectures became especially popular with the rise of tools such as Visual Basic and PowerBuilder.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        两层设计(在某些情况下)具有初始快速开发的优势,但可能会遭受 问题 部分所涵盖的抱怨。尽管如此,有些应用程序主要是简单的 CRUD(创建、检索、更新、删除)数据密集型系统,这是一个合适的选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Two-tier designs have (in some cases) the advantage of initial quick development, but can suffer the complaints covered in the Problems section. Nevertheless, there are applications that are primarily simple CRUD (create, retrieve, update, delete) data intensive systems, for which this is a suitable choice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 间接层可以向较低级别的服务添加间接级别。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Indirection layers can add a level of indirection to lower-level services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 受保护的变体层可以防止不同实施的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Protected Variation layers can protect against the impact of varying implementations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Low Coupling 和 High Cohesion 层强烈支持这些目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Low Coupling and High Cohesion layers strongly support these goals.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 它具体应用于面向对象的信息系统,在 [Fowler96] 中进行了描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Its application specifically to object-oriented information systems is described in [Fowler96].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        也称为

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Also Known As

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Layers 模式也称为分层架构 [Shaw96Gemstone00]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The Layers pattern is also known as Layered Architecture [Shaw96, Gemstone00].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          34.4. 模型-视图分离和“向上”通信

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          34.4. Model-View Separation and "Upward" Communication

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          窗口如何获取要显示的信息?通常,它们向域对象发送消息就足够了,查询信息,然后在 widgetsa 轮询或显示更新的 pull-from-above 模型中显示这些信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How can windows obtain information to display? Usually, it is sufficient for them to send messages to domain objects, querying for information which they then display in widgetsa polling or pull-from-above model of display updates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          但是,轮询模型有时是不够的。例如,每秒轮询数千个对象以仅发现一两个更改,然后使用这些更改来刷新 GUI 显示,效率不高。在这种情况下,当域对象的状态发生变化时,少数变化的域对象与窗口通信以导致显示更新会更有效。这种情况的典型情况包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          However, a polling model is sometimes insufficient. For example, polling every second across thousands of objects to discover only one or two changes, which are then used to refresh a GUI display, is not efficient. In this case it is more efficient for the few changing domain objects to communicate with windows to cause a display update as the state of domain objects changes. Typical situations of this case include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 监控应用程序,例如电信网络管理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Monitoring applications, such as telecommunications network management.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 需要可视化的仿真应用程序,例如空气动力学建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Simulation applications that require visualization, such as aerodynamics modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在这些情况下,需要显示更新的从下推送模型。由于模型-视图分离模式的限制,这导致需要从较低对象向上推送到窗口的“间接通信,以从下方推送通知以进行更新。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In these situations, a push-from-below model of display update is required. Because of the restriction of the Model-View Separation pattern, this leads to the need for "indirect" communication from lower objects up to windowspushing up notification to update from below.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有两种常见的解决方案:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          There are two common solutions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. Observer 模式,通过使 GUI 对象简单地显示为实现接口(如 PropertyListener)的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. The Observer pattern, via making the GUI object simply appear as an object that implements an interface such as PropertyListener.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. UI 外观对象。也就是说,在 UI 层中添加一个 Facade,用于接收来自下面的请求。这是添加 Indirection 以在 GUI 更改时提供 Protected Variation 的示例。例如,参见图 34.13

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 34.13.UI 层 UIFacade 偶尔用于从下推送的设计。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. A UI facade object. That is, adding a facade within the UI layer that receives requests from below. This is an example of adding Indirection to provide Protected Variation if the GUI changes. For example, see Figure 34.13.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Figure 34.13. A UI layer UIFacade is occasionally used for push-from-below designs.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            34.5. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            34.5. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            有大量关于分层体系结构的文献,包括印刷品和 Web 资料。Pattern Languages of Program Design, volume 1, [CS95] 中的一系列模式首先以模式形式解决了这个主题,尽管分层体系结构至少从 1960 年代就开始使用和撰写了相关文章;第 2 卷继续介绍更多与 Layers 相关的模式。面向模式的软件体系结构第 1 卷 [BMRSS96] 提供了对 Layers 模式的良好处理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            There's a wealth of literature on layered architectures, both in print and on the Web. A series of patterns in Pattern Languages of Program Design, volume 1, [CS95] first address the topic in pattern form, although layered architectures have been used and written about since at least the 1960s; volume 2 continues with further layers-related patterns. Pattern-Oriented Software Architecture volume 1 [BMRSS96] provides a good treatment of the Layers pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              第 35 章.使用 GoF Patterns 进行更多对象设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Chapter 35. More Object Design with GoF Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              有两次(国会议员)问我,“祈祷,巴贝奇先生,如果你把错误的数字放进机器里,会得出正确的答案吗?我无法正确地理解可能引发这样一个问题的那种思想混淆。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              查尔斯·巴贝奇

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              On two occasions I have been asked (by members of Parliament), "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Charles Babbage

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 在用例实现的设计中应用 GoF 和 GRASP。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Apply GoF and GRASP in the design of the use-case realizations.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                本章探讨了更多的 OO 设计,将 GoF 和 GRASP 模式应用于这两个案例研究的当前迭代。对于 NextGen POS,我们解决了故障转移到本地服务、POS 设备处理和支付授权等要求,同时演示了 GoF 模式的应用。对于垄断问题,我们解决了登陆房地产广场并购买或支付租金的问题。Monopoly(从第 607 页开始)演示了应用基本的 GRASP 原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This chapter explores more OO designs, applying GoF and GRASP patterns, to the current iteration of both case studies. For NextGen POS, we tackle requirements such as failover to local services, POS device handling, and payment authorization, while demonstrating applying GoF patterns. For the Monopoly problem, we tackle landing on property squares and buying or paying rent. Monopoly (starting on p. 607) demonstrates applying basic GRASP principles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  35.1. 示例:NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  35.1. Example: NextGen POS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  以下部分探讨了将模式和原则应用于各种迭代 3 NextGen 要求,包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The following sections explore applying patterns and principles to various iteration-3 NextGen requirements, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 当远程服务发生故障时故障转移到本地服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • failover to a local service when a remote service fails

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 本地缓存

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • local caching

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 支持第三方 POS 设备,例如不同的扫描仪

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • support for third-party POS devices, such as different scanners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 处理信用卡、借记卡和支票付款

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • handling credit, debit, and check payments

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    35.2. 故障转移到本地服务;本地缓存的性能

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    35.2. Failover to Local Services; Performance with Local Caching

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    NextGen 的要求之一是从远程服务故障(例如(暂时)不可用的产品数据库)中进行一定程度的恢复。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    One of the NextGen requirements is some degree of recovery from remote service failure, such as a (temporarily) unavailable product database.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    访问产品信息是用于探索恢复和故障转移设计策略的第一个案例。之后,探索对会计服务的访问,它的解决方案略有不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Access to product information is the first case used to explore the recovery and failover design strategy. Afterwards, access to the accounting service is explored, which has a slightly different solution.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    回顾部分技术备忘录:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To review part of the technical memo:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    技术备忘录:问题:可靠性从远程服务故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Technical Memo: Issue: ReliabilityRecovery from Remote Service Failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    解决方案摘要:使用服务查找、从远程到本地的故障转移以及本地服务部分复制实现位置透明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Solution Summary: Location transparency using service lookup, failover from remote to local, and local service partial replication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 从远程服务故障(例如,税收计算器、库存)中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Robust recovery from remote service failure (e.g., tax calculator, inventory)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 从远程产品(例如描述和价格)数据库故障中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Robust recovery from remote product (e.g., descriptions and prices) database failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    使用从 ServicesFactory 提供的 Adapter 实现与服务位置相关的受保护变体。在可能的情况下,提供远程服务的本地实现,通常具有简化或约束的行为。例如,当地税计算器将使用固定税率。本地产品信息数据库将是最常见产品的一小块缓存。库存更新将在重新连接时存储和转发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Achieve protected variation with respect to location of services using the Adapter served up from a ServicesFactory. Where possible, offer local implementations of remote services, usually with simplified or constrained behavior. For example, the local tax calculator will use constant tax rates. The local product information database will be a small cache of the most common products. Inventory updates will be stored and forwarded at reconnection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    另请参阅适应性第三方服务技术备忘录,了解此解决方案的适应性方面,因为远程服务实施在每次安装时都会有所不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    See also the AdaptabilityThird-Party Services technical memo for the adaptability aspects of this solutions, because remote service implementations will vary at each installation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    为了满足与远程服务重新连接的质量方案,请对服务使用智能代理对象,这些对象在每次服务调用时测试远程服务重新激活,并在可能时重定向到它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To satisfy the quality scenarios of reconnection with the remote services, use smart Proxy objects for the services, that on each service call test for remote service reactivation, and redirect to them when possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    零售商真的不想停止销售!因此,如果 NextGen POS 提供这种级别的可靠性和恢复能力,它将是一款非常有吸引力的产品,因为我们的竞争对手都没有提供这种功能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Retailers really don't want to stop making sales! Therefore, if the NextGen POS offers this level of reliability and recovery, it will be a very attractive product, as none of our competitors provide this capability.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在解决故障转移和恢复方面之前,请注意,出于性能原因和提高访问远程数据库失败时的可恢复性,架构师 (me) 建议使用 ProductDescription 对象的本地缓存(可靠地保存在本地硬盘上的简单文件中)。因此,在尝试远程访问之前,应始终在本地缓存中搜索“缓存命中”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Before solving the failover and recovery aspects, note that for both performance reasons and to improve recoverability when access to the remote database fails, the architect (me) has recommended a local cache (reliably persisted on the local hard disk in a simple file) of ProductDescription objects. Therefore, the local cache should always be searched for a "cache hit" before attempting a remote access.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这可以通过我们现有的适配器和工厂设计巧妙地实现:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This can be neatly achieved with our existing adapter and factory design:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. ServicesFactory 将始终将适配器返回到本地产品信息服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. The ServicesFactory will always return an adapter to a local product information service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    3. 本地产品的 “adapter” 并不是另一个组件的真正适配器。它本身将履行本地服务的责任。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    4. The local products "adapter" is not really an adapter to another component. It will itself implement the responsibilities of the local service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    5. 本地服务初始化为对真正远程产品服务的第二个适配器的引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    6. The local service is initialized to a reference to a second adapter to the true remote product service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    7. 如果本地服务在其缓存中找到数据,则会返回该数据;否则,它会将请求转发到外部服务的适配器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    8. If the local service finds the data in its cache, it returns it; otherwise, it forwards the request to the adapter for the external service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    请注意,客户端缓存有两个级别:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Note that there are two levels of client-side cache:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    1. 内存中的 ProductCatalog 对象将维护一些(例如,1,000 个)ProductDescription 对象的内存中集合(例如 Java HashMap),这些对象是从产品信息服务中检索到的。可以根据本地内存可用性调整此集合的大小。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    2. The in-memory ProductCatalog object will maintain an in-memory collection (such as a Java HashMap) of some (for example, 1,000) ProductDescription objects that have been retrieved from the product information service. The size of this collection can be adjusted depending on local memory availability.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    3. 本地产品服务将维护一个更大的持久性 (基于硬盘) 缓存,以维护一定数量的产品信息(例如 1 MB 或 100MB 的文件空间)。同样,它可以根据本地配置进行调整。此持久性缓存对于容错非常重要,因此,即使 POS 应用程序崩溃并且 ProductCatalog 对象的内存中缓存丢失,持久性缓存也会保留。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    4. The local products service will maintain a larger persistent (hard disk based) cache that maintains some quantity of product information (such as 1 or 100MB of file space). Again, it can be adjusted depending on the local configuration. This persistent cache is important for fault tolerance, so that even if the POS application crashes and the in-memory cache of the ProductCatalog object is lost, the persistent cache remains.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    此设计不会破坏现有代码插入新的本地服务对象,而不会影响 ProductCatalog 对象(与产品服务协作)的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This design does not break existing codethe new local service object is inserted without affecting the design of the ProductCatalog object (which collaborates with the product service).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    到目前为止,尚未引入任何新模式;使用 Adapter 和 Factory。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    So far, no new patterns have been introduced; Adapter and Factory are used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.1 说明了设计中的类型,图 35.2 说明了初始化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Figure 35.1 illustrates the types in the design, and Figure 35.2 illustrates the initialization..

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.1.用于产品信息的适配器。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.2.产品信息服务的初始化。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.3 显示了从 catalog 到 products 服务的初始协作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Figure 35.3 shows the initial collaboration from the catalog to the products service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.3.开始与 products 服务的协作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果本地 product service 的缓存中没有 product,它会与外部服务的适配器协作,如图 35.4 所示。请注意,本地产品服务将 ProductDescription 对象缓存为 true 序列化对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If the local product service does not have the product in its cache, it collaborates with the adapter to the external service, as shown in Figure 35.4. Note that the local product service caches the ProductDescription objects as true serialized objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.4.继续合作以获取产品信息。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果真正的外部服务从数据库更改为新的 Web 服务,则只需更改远程服务的工厂配置。参见图 35.5

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If the true external service was changed from a database to a new Web service, only the factory's configuration of the remote service needs to change. See Figure 35.5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.5.新的外部服务不会影响设计。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    为了继续与 DBProductsAdapter 协作,它将与对象关系 (O-R) 映射持久性子系统进行交互(参见图 35.6)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To continue with the case of collaborating with the DBProductsAdapter, it will interact with an object-relational (O-R) mapping persistence subsystem (see Figure 35.6).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.6.与持久化子系统协作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    缓存策略

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Caching Strategies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    考虑加载内存中 ProductCatalog 缓存和基于 LocalProducts 文件的缓存的替代方法:一种方法是延迟初始化,其中缓存在检索外部产品信息时缓慢填充;另一种方法是 Eager Initialization,其中缓存在 StartUp 使用案例期间加载。如果设计人员不确定使用哪种方法并希望尝试其他选择,那么基于 Strategy 模式的不同 CacheStrategy 对象系列可以巧妙地解决问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Consider the alternatives for loading the in-memory ProductCatalog cache and the LocalProducts file-based cache: One approach is lazy initialization, in which the caches fill slowly as external product information is retrieved; another approach is eager initialization, in which the caches are loaded during the StartUp use case. If the designer is unsure which approach to use and wants to experiment with alternatives, a family of different CacheStrategy objects based on the Strategy pattern can neatly solve the problem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    过时的缓存

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Stale Cache

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    由于产品价格变化很快,而且可能是商店经理的心血来潮,缓存产品价格会产生一个问题缓存包含过时的数据;在复制数据时,这始终是一个问题。一种解决方案是添加一个远程服务操作来响应当今的变化;LocalProducts 对象每 n 分钟查询一次它并更新其缓存。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Since product prices change quickly, and perhaps at the whim of the store manager, caching the product price creates a problemthe cache contains stale data; this is always a concern when data is replicated. One solution is to add a remote service operation that answers today's current changes; the LocalProducts object queries it every n minutes and updates its cache.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    UML 中的线程

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Threads in the UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    如果 LocalProducts 对象要解决每 n 分钟更新一次的查询的过时缓存问题,则一种设计方法是使其成为拥有控制线程的活动对象。线程将休眠 n 分钟,然后唤醒,对象将获取数据,线程将重新进入休眠状态。UML 提供了表示法来说明线程和异步调用,如图 35.7图 35.8 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If the LocalProducts object is going to solve the stale cache problem with a query for updates every n minutes, one approach to the design is to make it an active object that owns a thread of control. The thread will sleep for n minutes, wake up, the object will get the data, and the thread will go back to sleep. The UML provides notation to illustrate threads and asynchronous calls, as shown in Figure 35.7 and Figure 35.8.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.7.UML 中的线程和异步消息。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 35.8.Active 类表示法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      35.3. 处理失败

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      35.3. Handling Failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      上述设计为持久性文件中的 ProductDescription 对象的客户端缓存提供了一种解决方案,以提高性能,并在无法访问外部 products 服务时至少提供部分回退解决方案。本地文件中可能缓存了 10,000 个产品,即使外部服务失败,也可以满足大多数产品信息请求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The preceding design provides a solution for client-side caching of ProductDescription objects in a persistent file, to improve performance, and also to provide at least a partial fall-back solution if the external products service can't be accessed. Perhaps 10,000 products are cached in the local file, which may satisfy most requests for product information even when the external service fails.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果没有本地缓存命中并且对外部 products 服务的访问失败,该怎么办?假设利益相关者要求我们创建一个解决方案,向收银员发出信号,以手动输入价格和描述,或取消行项目输入。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What to do in the case where there isn't a local cache hit and access to the external products service fails? Suppose that the stakeholders asked us create a solution that signals the cashier to manually enter the price and description, or cancel the line item entry.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这是错误或失败条件的一个示例,它将用作上下文来描述处理失败和异常处理的一些一般模式。异常和错误处理是一个很大的主题,本简介将只关注特定于案例研究上下文的一些模式。首先,一些术语:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is an example of an error or failure condition, and it will be used as a context to describe some general patterns in dealing with failures and exception handling. Exception and error handling is a large topic, and this introduction will just focus on some patterns specific to the context of the case study. First, some terminology:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 过错是不当行为的最终起源或原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 程序员拼错了数据库的名称。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Fault the ultimate origin or cause of misbehavior.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Programmer misspelled the name of a database.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 错误 正在运行的系统中故障的表现形式。检测到 (或未) 检测到错误。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 当调用命名服务以获取对数据库的引用(名称拼写错误)时,它会发出错误信号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Error a manifestation of the fault in the running system. Errors are detected (or not).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • When calling the naming service to obtain a reference to the database (with the misspelled name), it signals an error.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Failure (失败) 由错误导致的拒绝服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Products 子系统(和 NextGen POS)无法提供产品信息服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Failure a denial of service caused by an error.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The Products subsystem (and the NextGen POS) fails to provide a product information service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      引发异常

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Throwing Exceptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      向正在考虑的失败发出信号的一种直接方法是引发异常。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A straightforward approach to signaling the failure under consideration is to throw an exception.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在处理资源故障(磁盘、内存、网络或数据库访问以及其他外部服务)时,异常尤其适用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Exceptions are especially appropriate when dealing with resource failures (disk, memory, network or database access, and other external services).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      将从持久化子系统中引发异常(实际上,可能从类似 Java JDBC 实现的内容开始),其中首先检测到使用外部 products 数据库的失败。该异常会将调用堆栈展开回适当的处理点。[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An exception will be thrown from within the persistence subsystem (actually, probably starting from within something like a Java JDBC implementation), where a failure to use the external products database is first detected. The exception will unwind the call stack back up to an appropriate point for its handling.[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [1] 未涵盖已检查与未检查的异常处理,因为并非所有流行的 OO 语言 C++、C# 和 Smalltalk 都支持它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [1] Checked vs. unchecked exception handling is not covered, as it is not supported in all popular OO languagesC++, C#, and Smalltalk, for example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      假设原始异常(以 Java 为例)是 java.sql.SQLException。是否应该将 SQLException 本身一直抛出到表示层?不。它处于错误的抽象层次。这导致了一种常见的异常处理模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Suppose that the original exception (using Java as an example) is a java.sql.SQLException. Should a SQLException per se be thrown all the way up to the presentation layer? No. It is at the wrong level of abstraction. This leads to a common exception handling pattern:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      模式:转换异常 [Brown01]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern: Convert Exceptions [Brown01]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在子系统中,避免从较低级别的子系统或服务发出较低级别的异常。相反,将较低级别的异常转换为在子系统级别有意义的异常。较高级别的异常通常包装较低级别的异常,并添加信息,以使异常在上下文中对较高级别更具意义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Within a subsystem, avoid emitting lower level exceptions coming from lower subsystems or services. Rather, convert the lower level exception into one that is meaningful at the level of the subsystem. The higher level exception usually wraps the lower-level exception, and adds information, to make the exception more contextually meaningful to the higher level.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这是一个指导方针,而不是绝对的规则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is a guideline, not an absolute rule.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “Exception”在这里用于可以抛出的东西的白话意义上;在 Java 中,等效物是 Throwable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      "Exception" is used here in the vernacular sense of something that can be thrown; in Java, the equivalent is a Throwable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      也称为异常抽象 [Renzel97]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Also known as Exception Abstraction [Renzel97].



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,持久化子系统捕获特定的 SQLException,并且(假设它无法处理它[2] )抛出一个新的 DBUnavailableException,其中包含 SQLException。请注意,DBProductAdapter 就像产品信息的逻辑子系统上的门面。因此,较高级别的 DBProductAdapter(作为逻辑子系统的代表)捕获较低级别的 DBUnavailableException,并(假设它无法处理它)引发一个新的 ProductInfoUnavailableException,该异常包装 DBUnavailableException

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, the persistence subsystem catches a particular SQLException, and (assuming it can't handle it[2] ) throws a new DBUnavailableException, which contains the SQLException. Note that the DBProductAdapter is like a facade onto a logical subsystem for product information. Thus, the higher level DBProductAdapter (as the representative for a logical subsystem) catches the lower level DBUnavailableException and (assuming it can't handle it) throws a new ProductInfoUnavailableException, which wraps the DBUnavailableException.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [2] 解决接近引发异常的级别是一个值得称赞但困难的目标,因为如何处理错误的要求通常是特定于应用程序的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [2] Resolving an exception near the level at which it was raised is a laudable but difficult goal, because the requirement for how to handle an error is often application-specific.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      考虑这些异常的名称:为什么是 DBUnavailableException 而不是 PersistenceSubsystemException?这有一个模式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Consider the names of these exceptions: Why DBUnavailableException rather than, say, PersistenceSubsystemException? There is a pattern for this:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图案:命名问题而不是投掷者 [Grosso00]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern: Name The Problem Not The Thrower [Grosso00]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如何称呼异常?分配一个名称,该名称描述引发异常的原因,而不是引发者。好处是它使程序员更容易理解问题,并且它突出了许多异常类的本质相似性(在某种程度上,命名 thrower 则不会)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What to call an exception? Assign a name that describes why the exception is being thrown, not the thrower. The benefit is that it makes it easier for the programmer to understand the problem, and it the highlights the essential similarity of many classes of exceptions (in a way that naming the thrower does not).



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UML 中的异常

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Exceptions in the UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      现在是引入 UML 表示法的合适时机,用于引发[3] 和捕获异常。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is an appropriate time to introduce the UML notation for throwing[3] and catching exceptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [3] 在 UML 中,官方会发送异常,但 throws 是一个足够且更熟悉的用法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [3] Officially in the UML, one sends an exception, but throws is a sufficient and more familiar usage.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UML 中的两个常见表示法问题是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Two common notation questions in the UML are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. 在类图中,如何显示类捕获和抛出的异常?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. In a class diagram, how to show what exceptions a class catches and throws?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. 在交互图中,如何显示引发异常?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4. In an interaction diagram, how to show throwing an exception?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对于类图,图 35.9 显示了以下表示法:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For a class diagram, Figure 35.9 presents the notation:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 35.9.类捕获并引发的异常。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 UML 中,ExceptionSignal 的特化,它是对象之间异步通信的规范。这意味着在交互图中,异常表示为异步消息[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In the UML, an Exception is a specialization of a Signal, which is the specification of an asynchronous communication between objects. This means that in interaction diagrams, exceptions are illustrated as asynchronous messages.[4]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [4] 请注意,从 UML 1.4 开始,异步消息的表示法从半箭头变为棒状箭头。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [4] Note that starting in UML 1.4, the notation for an asynchronous message changed from a half arrowhead to a stick arrowhead.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 35.10 显示了表示法,使用转换为 DBUnavailableExceptionSQLException 的先前描述作为示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 35.10 shows the notation, using the prior description of SQLException translated to DBUnavailableException as an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 35.10.交互图中的异常。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      总之,UML 表示法的存在是为了显示异常。但是,它很少使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In summary, UML notation exists to show exceptions. However, it is rarely used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这不是避免早期考虑异常处理的建议。恰恰相反:在体系结构级别,需要尽早建立异常处理的基本模式、策略和协作,因为事后插入异常处理很尴尬。但是,许多开发人员认为,处理特定异常的低级设计在编程过程中或通过不太详细的设计描述来决定,而不是通过详细的 UML 图来决定。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is not a recommendation to avoid early consideration of exception handling. Quite the opposite: At an architectural level, the basic patterns, policies, and collaborations for exception handling need to be established early, because it is awkward to insert exception handling as an afterthought. However, the low-level design of handling particular exceptions is felt by many developers to be most appropriately decided during programming or via less detailed design descriptions, rather than via detailed UML diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      处理错误

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Handling Errors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      已经考虑了设计的一方面:在转换、命名和说明它们方面抛出异常。另一端是异常的处理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      One side of the design has been considered: throwing exceptions, in terms of converting, naming, and illustrating them. The other side is the handling of an exception.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在这种情况下和大多数情况下,要应用的两种模式是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Two patterns to apply in this and most cases are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      模式:集中式错误日志记录 [renzel97]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern: Centralized Error Logging [Renzel97]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      使用单一实例访问的中央错误日志记录对象,并向其报告所有异常。如果它是一个分布式系统,则每个本地 singleton 都将与一个中央错误记录器协作。好处:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Use a Singleton-accessed central error logging object and report all exceptions to it. If it is a distributed system, each local singleton will collaborate with a central error logger. Benefits:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 报告的一致性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Consistency in reporting.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 灵活定义输出流和格式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Flexible definition of output streams and format.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      也称为诊断记录器 [Harrison98]。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Also known as Diagnostic Logger [Harrison98].



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这是一个简单的模式。第二个是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It is a simple pattern. The second is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      模式:错误对话框 [renzel97]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern: Error Dialog [Renzel97]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      使用标准的单例访问、独立于应用程序的非 UI 对象来通知用户错误。它包装一个或多个 UI“对话框”对象(例如 GUI 模式对话框、文本控制台、声音蜂鸣器或语音生成器),并将错误通知委托给 UI 对象。因此,输出可以同时转到 GUI 对话框和语音生成器。它还会将异常报告给集中式错误记录器。Factory 从系统参数中读取数据将创建相应的 UI 对象。好处:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Use a standard Singleton-accessed, application-independent, non-UI object to notify users of errors. It wraps one or more UI "dialog" objects (such as a GUI modal dialog, text console, sound beeper, or speech generator) and delegates the notification of the error to the UI objects. Thus, output could go to both a GUI dialog and to a speech generator. It will also report the exception to the centralized error logger. A Factory reading from system parameters will create the appropriate UI objects. Benefits:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Protected Variations 与输出机制中的更改有关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Protected Variations with respect to changes in the output mechanism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 一致的错误报告风格;例如,所有 GUI 窗口都可以调用此单例来显示 Error 对话框。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Consistent style of error reporting; for example, all GUI windows can call on this singleton to display the error dialog.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 集中控制错误通知的通用策略。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Centralized control of the common strategy for error notification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 性能提升较小;如果使用了 “昂贵” 的资源,例如 GUI 对话框,则很容易隐藏和缓存它以供回收使用,而不是为每个错误重新创建一个对话框。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Minor performance gain; if an "expensive" resource such as a GUI dialog is used, it is easy to hide and cache it for recycled use, rather than recreate a dialog for each error.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      UI 对象(例如 ProcessSaleFrame)是否应该通过捕获异常并通知用户来处理错误?对于只有几个窗口的应用程序,以及窗口之间简单、稳定的导航路径,这种简单的设计很好。目前,NextGen 应用程序也是如此。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Should a UI object (for example, ProcessSaleFrame) handle an error by catching the exception and notifying the user? For applications with only a few windows, and simple, stable navigation paths between windows, this straightforward design is fine. This is currently true for the NextGen application.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      但是请记住,这会在表示 (GUI) 层中放置一些与错误处理相关的 “应用程序逻辑”。错误处理与用户通知有关,因此这是合乎逻辑的,但这是一个值得关注的趋势。对于 UI 替换可能性较低的简单 UI 来说,这本身并不是一个问题,但这是一个脆弱点。例如,假设一个团队希望将 Java Swing UI 替换为用于掌上计算机的 IBM Java MicroView GUI 框架。现在,Swing 版本中有一些应用程序逻辑必须在 MicroView 版本中识别和复制。在某种程度上,这对于 UI 替换来说是不可避免的;但随着更多的应用程序 logic 向上迁移,这种情况会加剧。一般来说,随着越来越多的非 UI 应用程序逻辑责任迁移到表示层,设计或维护麻烦的可能性会增加。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Keep in mind, however, that this places some "application logic" related to error handling in the presentation (GUI) layer. The error handling relates to user notification, so this is logical, but it is a trend to watch. It is not inherently a problem for simple UIs with a low chance of UI replacement, but it is a point of fragility. For example, suppose a team wants to replace a Java Swing UI with the IBM Java MicroView GUI framework for handheld computers. There is now some application logic in the Swing version that has to be identified and replicated in the MicroView version. To some degree, this is inevitable with UI replacements; but it will be aggravated as more application logic migrates upwards. In general, as more non-UI application logic responsibilities migrate to the presentation layer, the probability of design or maintenance headaches increases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对于具有许多窗口和复杂(甚至可能更改)导航路径的系统,还有其他解决方案。例如,可以在 presentation 层和域层之间插入一个或多个控制器的应用程序层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For systems with many windows and complex (perhaps even changing) navigation paths, there are other solutions. For example, an application layer of one or more controllers can be inserted between the presentation and domain layers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      此外,可以插入一个“视图管理器中介”对象 [GHJV95BMRSS96],它负责引用所有打开的窗口,并知道窗口之间的转换,给定一些事件 E1(比如错误)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Furthermore, a "view manager mediator" object [GHJV95, BMRSS96] that is responsible for having a reference to all open windows, and knowing the transitions between windows, given some event E1 (such as an error), can be inserted.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这个中介器抽象地是一个状态机,它根据事件封装状态 (显示窗口) 和状态之间的转换。它可以从外部文件中读取状态 (窗口) 过渡模型,以便导航路径可以是数据驱动的(不需要更改源代码)。它还可以关闭所有应用程序窗口,或者平铺或最小化它们,因为它具有对所有窗口的引用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This mediator is abstractly a state machine that encapsulates the states (displayed window) and transitions between states, based on events. It may read the state (window) transition model from an external file, so that the navigation paths can be data-driven (source code changes are not necessary). It can also close all the application windows, or tile or minimize them, since it has a reference to all windows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在此 design中,可以设计一个 application layer controller 并引用此 view manager 中介器(因此,application controller “向上”耦合到表示层)。应用程序控制器可能会捕获异常并与视图管理器中介器协作以引起通知(基于 Error Dialog 模式)。这样,应用程序控制器就参与了应用程序的工作流,并且一些错误逻辑处理被排除在窗口之外。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In this design, an application layer controller may be designed with a reference to this view manager mediator (hence, the application controller is coupled "upwards" to the presentation layer). The application controller may catch the exception and collaborate with the view manager mediator to cause notification (based on the Error Dialog pattern). In this way, the application controller is involved with workflow for the application, and some error logic handling is kept out of the windows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      详细的 UI 控件和导航设计超出了本介绍的范围,窗口捕获异常的简单设计就足够了。使用 Error Dialog 的设计如图 35.11 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Detailed UI control and navigation design is outside the scope of this introduction, and the simple design of the window catching the exception will suffice. A design using an Error Dialog is shown in Figure 35.11.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 35.11.处理异常。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        35.4. 使用代理 (GoF) 故障转移到本地服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        35.4. Failover to Local Services with a Proxy (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        通过将本地服务插入到外部服务的前面,可以实现产品信息到本地服务的故障转移;始终首先尝试本地服务。但是,此设计并不适合所有服务;有时应该先尝试外部服务,然后再尝试本地版本。例如,考虑将销售过帐到会计服务。企业希望尽快发布它们,以便实时跟踪商店和收银机活动。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Failover to a local service for the product information was achieved by inserting the local service in front of the external service; the local service is always tried first. However, this design is not appropriate for all services; sometimes the external service should be tried first, and a local version second. For example, consider the posting of sales to the accounting service. Business wants them posted as soon as possible, for real-time tracking of store and register activity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在这种情况下,另一种 GoF 模式可以解决问题:Proxy。Proxy 是一种简单的模式,广泛用于其 Remote Proxy 变体。例如,在 Java 的 RMI 和 CORBA 中,调用本地客户端对象(称为“存根”)来访问远程对象的服务。客户端存根是本地代理或远程对象的代表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In this case, another GoF pattern can solve the problem: Proxy. Proxy is a simple pattern, and widely used in its Remote Proxy variant. For example, in Java's RMI and in CORBA, a local client-side object (called a "stub") is called upon to access a remote object's services. The client-side stub is a local proxy, or a representative for a remote object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此 NextGen 代理示例使用不是远程代理变体,而是重定向代理(也称为故障转移代理)变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This NextGen example use of Proxy is not the Remote Proxy variant, but rather the Redirection Proxy (also known as a Failover Proxy) variant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        无论变体如何,Proxy 的结构始终相同;这些变体与 Proxy 曾经调用的内容有关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Regardless of the variant, the structure of Proxy is always the same; the variations are related to what the proxy does once called.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        代理只是一个对象,它实现与 Subject 对象相同的接口,保存对真实 Subject 的引用,并用于控制对它的访问。有关一般结构,请参见图 35.12

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A proxy is simply an object that implements the same interface as the subject object, holds a reference to the real subject, and is used to control access to it. For the general structure, see Figure 35.12.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 35.12.Proxy 模式的一般结构。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Proxy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        上下文/问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Context/Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        直接访问真实的主题对象是不可取的,也是不可能的。该怎么办?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Direct access to a real subject object is not desired or possible. What to do?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        使用代理代理对象添加间接级别,该代理对象实现与主题对象相同的接口,并负责控制或增强对它的访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Add a level of indirection with a surrogate proxy object that implements the same interface as the subject object, and is responsibility for controlling or enhancing access to it.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        应用于外部会计服务访问的 NextGen 案例研究,重定向代理的使用方式如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Applied to the NextGen case study for external accounting service access, a redirection proxy is used as follows:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 向重定向代理发送 postSale 消息,将其视为实际的外部会计服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Send a postSale message to the redirection proxy, treating it as though it was the actual external accounting service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 如果重定向代理无法与外部服务取得联系(通过其适配器),则它会将 postSale 消息重定向到本地服务,该服务在本地存储销售以转发到会计服务(当它处于活动状态时)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. If the redirection proxy fails to make contact with the external service (via its adapter), then it redirects the postSale message to a local service, which locally stores the sales for forwarding to the accounting service, when it is active.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 35.13 说明了 Interesting Elements 的类图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Figure 35.13 illustrates a class diagram of the interesting elements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 35.13.NextGen 使用重定向代理。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        应用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Applying UML:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 为避免创建交互图来显示动态行为,请观察此静态图如何使用编号来传达交互顺序。交互图通常是首选,但提供此样式是为了说明另一种样式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • To avoid creating an interaction diagram to show the dynamic behavior, observe how this static diagram uses numbering to convey the sequence of interaction. An interaction diagram is usually preferred, but this style is presented to illustrate an alternative style.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 观察 Register 方法旁边的 public 和 private ( +, - ) 可见性标记。如果不存在,则不指定它们,而不是默认为 public 或 private。但是,根据通常的约定,大多数读者(和生成 CASE 工具的代码)将未指定的可见性解释为表示私有属性和公共方法。但是,在此图中,我特别想传达 makePayment 是 public 的事实,相比之下,completeSaleHandling 是 private。视觉噪音和信息过载始终是交流中的问题,因此最好利用传统解释来保持图表简单。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Observe the public and private ( +, - ) visibility markers beside Register methods. If absent, they are unspecified, rather than defaulting to public or private. However, by common convention, unspecified visibility is interpreted by most readers (and code generating CASE tools) as meaning private attributes and public methods. However, in this diagram, I especially want to convey the fact that makePayment is public, and by contrast, completeSaleHandling is private. Visual noise and information overload are always concerns in communication, so it is desirable to exploit conventional interpretation to keep the diagrams simple.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        总而言之,代理是包装内部对象的外部对象,并且两者都实现相同的接口。客户端对象(例如 Register)不知道它引用了代理,它的设计就像它与真正的主题(例如 SAPAccountingAdapter)协作一样。代理拦截调用以增强对真实主题的访问,在这种情况下,如果外部服务无法访问,则通过将操作重定向到本地服务 (LocalAccounting)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To summarize, a proxy is an outer object that wraps an inner object, and both implement the same interface. A client object (such as a Register) does not know that it references a proxyit is designed as though it is collaborating with the real subject (for example, the SAPAccountingAdapter). The Proxy intercepts calls in order to enhance access to the real subject, in this case by redirecting the operation to a local service (LocalAccounting) if the external service is not accessible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          35.5. 针对非功能或质量需求进行设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          35.5. Designing for Non-Functional or Quality Requirements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在继续下一节之前,请注意,本章到目前为止的设计工作与业务逻辑无关,而是与可靠性和恢复相关的非功能性或质量需求有关。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Before moving on to the next section, notice that the design work up to this point in the chapter did not relate to business logic, but to non-functional or quality requirements related to reliability and recovery.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有趣的是,这是软件架构中的一个关键点,软件架构的大规模主题、模式和结构通常由设计塑造,以解决非功能性或质量需求,而不是基本的业务逻辑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Interestinglyand this a key point in software architectureit is common that the large-scale themes, patterns, and structures of the software architecture are shaped by the designs to resolve the non-functional or quality requirements, rather than the basic business logic.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            35.6. 使用适配器访问外部物理设备

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            35.6. Accessing External Physical Devices with Adapters

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            此迭代中的另一个要求是与构成 POS 终端的物理设备进行交互,例如打开现金抽屉、从硬币分配器分配零钱以及从数字签名设备捕获签名。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Another requirement in this iteration is to interact with physical devices that comprise a POS terminal, such as opening a cash drawer, dispensing change from the coin dispenser, and capturing a signature from the digital signature device.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            NextGen POS 必须与各种 POS 设备配合使用,包括 IBM、Epson、NCR、Fujitsu 等销售的设备。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The NextGen POS must work with a variety of POS equipment, including that sold by IBM, Epson, NCR, Fujitsu, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            幸运的是,软件架构师做了一些调查,发现现在有一个行业标准 UnifiedPOS (www.nrf-arts.org),它为所有常见的 POS 设备定义了标准的面向对象的接口(在 UML 意义上)。此外,还有 JavaPOS (www.javapos.com)UnifiedPOS 的 Java 映射。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Fortunately, the software architect has done some investigation, and has discovered that there is now an industry standard, UnifiedPOS (www.nrf-arts.org), that defines standard object-oriented interfaces (in the UML sense) for all common POS devices. Furthermore, there is the JavaPOS (www.javapos.com)a Java mapping of the UnifiedPOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            因此,在 Software Architecture Document 中,架构师添加了一个技术备忘录来传达这个重要的架构选择:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Therefore, in the Software Architecture Document, the architect adds a technical memo to communicate this significant architectural choice:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            技术备忘录:问题:POS 硬件设备控制

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Technical Memo: Issue: POS Hardware Device Control

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            解决方案摘要:使用设备制造商提供的符合 JavaPOS 标准接口的 Java 软件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Solution Summary: Use Java software from the device manufacturers that conforms to the JavaPOS standard interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 正确控制设备

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Correctly controls the devices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 购买成本与构建和维护成本

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Cost to buy vs. build and maintain

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            UnifiedPOS (www.nrf-arts.org) 为 POS 设备定义了接口的行业标准 UML 模型。JavaPOS (www.javapos.com) 是 UnifiedPOS 到 Java 的行业标准映射。POS 设备制造商(例如 IBM、NCR)销售这些接口的 Java 实现,这些接口用于控制其设备。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The UnifiedPOS (www.nrf-arts.org) defines an industry standard UML model of interfaces for POS devices. The JavaPOS (www.javapos.com) is an industry standard mapping of UnifiedPOS to Java. POS device manufactures (e.g., IBM, NCR) sell Java implementations of these interfaces that control their devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            购买这些,而不是建造它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Buy these, rather than build them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用从系统属性中读取的 Factory 来加载 IBM 或 NCR(等)类集,并根据它们的接口返回实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use a Factory that reads from a system property to load IBM or NCR (etc.) set of classes, and return instances based on their interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            根据一项非正式调查,我们认为它们运行良好,并且制造商有一个定期的更新流程来改进它们。很难获得专业知识和其他资源来自己编写这些内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Based on an informal survey, we believe they work well, and the manufacturers have a regular update process for their improvement. It is difficult to get the expertise and other resources to write these ourselves.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            考虑的替代方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Alternatives Considered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            自己写它们——困难且有风险。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Writing them ourselves--difficult and risky.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 35.14 显示了一些接口,这些接口已作为域层的另一个包添加到我们的 Design Model 中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Figure 35.14 shows some of the interfaces, which have been added as another package of the domain layer in our Design Model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 35.14.标准 JavaPOS 接口。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            假设 POS 设备的主要制造商现在提供 JavaPOS 实现。例如,如果我们购买带有现金抽屉、硬币分配器等的 IBM POS 终端,我们还可以从 IBM 获得实现 JavaPOS 接口并控制物理设备的 Java 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Assume that the major manufacturers of POS equipment now provide JavaPOS implementations. For example, if we buy an IBM POS terminal with a cash drawer, coin dispenser, and so forth, we can also get Java classes from IBM that implement the JavaPOS interfaces, and that control the physical devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            因此,这部分架构是通过购买软件组件来解决的,而不是通过构建它们来解决的。鼓励使用现有组件是 UP 最佳实践之一。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Consequently, this part of the architecture is resolved by buying software components, rather than building them. Encouraging the use of existing components is one of the UP best practices.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            它们是如何工作的?在较低级别上,物理设备具有基础操作系统的设备驱动程序。一个 Java 类(例如,实现 jpos.CashDrawer) 使用 JNI(Java 本机接口)来调用这些设备驱动程序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How do they work? At a low level, a physical device has a device driver for the underlying operating system. A Java class (for example, one that implements jpos.CashDrawer) uses JNI (Java Native Interface) to make calls out to these device drivers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            这些 Java 类使低级设备驱动程序适应 JavaPOS 接口,因此可以被描述为 GoF 模式意义上的 Adapter 对象。它们也可以称为 Proxy objects本地代理,用于控制或增强对物理设备的访问。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            These Java classes adapt the low-level device driver to the JavaPOS interfaces, and thus can be characterized as Adapter objects in the GoF pattern sense. They can also be called Proxy objectslocal proxies that control or enhance access to the physical devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            能够根据多个模式对设计进行分类的情况并不少见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            It is not uncommon to be able to classify a design in terms of multiple patterns.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              35.7. 相关对象系列的抽象工厂 (GoF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              35.7. Abstract Factory (GoF) for Families of Related Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              JavaPOS 实现将从制造商处购买。例如[5]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The JavaPOS implementations will be purchased from manufacturers. For example[5] :

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [5] 这些是虚构的软件包名称。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [5] These are fictitious package names.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // IBM's drivers
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ibm.pos.jpos.CashDrawer (implements jpos.CashDrawer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ibm.pos.jpos.CoinDispenser (implements jpos.CoinDispenser)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // NCR's drivers
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ncr.posdrivers.CashDrawer (implements jpos.CashDrawer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ncr.posdrivers.CoinDispenser (implements jpos.CoinDispenser)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // IBM's drivers
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ibm.pos.jpos.CashDrawer (implements jpos.CashDrawer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ibm.pos.jpos.CoinDispenser (implements jpos.CoinDispenser)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // NCR's drivers
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ncr.posdrivers.CashDrawer (implements jpos.CashDrawer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              com.ncr.posdrivers.CoinDispenser (implements jpos.CoinDispenser)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              现在,如何设计 NextGen POS 应用程序以使用 IBM Java 驱动程序(如果使用 IBM 硬件)、NCR 驱动程序(如果适用)等等?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Now, how to design the NextGen POS application to use the IBM Java drivers if IBM hardware is used, NCR drivers if appropriate, and so forth?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              请注意,需要创建类族 (CashDrawer+CoinDispenser+...),并且每个族都实现相同的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Note that there are families of classes (CashDrawer+CoinDispenser+...) that need to be created, and each family implements the same interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对于这种情况,存在一种常用的 GoF 模式:Abstract Factory。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For this situation, a commonly used GoF pattern exists: Abstract Factory.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              抽象工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Abstract Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              上下文/问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Context/Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如何创建实现公共接口的相关类的系列?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How to create families of related classes that implement a common interface?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              定义工厂接口 (抽象工厂)。为要创建的每个事物系列定义一个具体的 factory 类。(可选)定义一个真正的抽象类,该类实现工厂接口,并为扩展该接口的具体工厂提供公共服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Define a factory interface (the abstract factory). Define a concrete factory class for each family of things to create. Optionally, define a true abstract class that implements the factory interface and provides common services to the concrete factories that extend it.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 35.15 说明了基本概念;下一节将对其进行改进。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Figure 35.15 illustrates the basic idea; it is improved upon in the next section.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 35.15.一个基本的抽象工厂。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              抽象类抽象工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              An Abstract Class Abstract Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              抽象工厂的一个常见变体是创建一个抽象类工厂,该工厂使用 Singleton 模式访问,从系统属性中读取以决定要创建哪个子类工厂,然后返回适当的子类实例。例如,在 Java 库中使用 java.awt.Toolkit 类,该类是一个抽象类抽象工厂,用于为不同的操作系统和 GUI 子系统创建 GUI 窗口小部件系列。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A common variation on Abstract Factory is to create an abstract class factory that is accessed using the Singleton pattern, reads from a system property to decide which of its subclass factories to create, and then returns the appropriate subclass instance. This is used, for example, in the Java libraries with the java.awt.Toolkit class, which is an abstract class abstract factory for creating families of GUI widgets for different operating system and GUI subsystems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这种方法的优点是它解决了这个问题:应用程序如何知道要使用哪个抽象工厂?IBMJavaPOSDevicesFactoryNCRJavaPOSDevicesFactory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The advantage of this approach is that it solves this problem: How does the application know which abstract factory to use? IBMJavaPOSDevicesFactory? NCRJavaPOSDevicesFactory?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              以下优化解决了这个问题。图 35.16 说明了解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The following refinement solves this problem. Figure 35.16 illustrates the solution.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 35.16.抽象类 abstract factory。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              使用这个抽象类工厂和单例模式 getInstance 方法,对象可以与抽象超类协作,并获得对其子类实例之一的引用。例如,请考虑以下语句:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              With this abstract class factory and Singleton pattern getInstance method, objects can collaborate with the abstract superclass, and obtain a reference to one of its subclass instances. For example, consider the statement:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              cashDrawer = JavaPOSDevicesFactory.getInstance().getNewCashDrawer();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              cashDrawer = JavaPOSDevicesFactory.getInstance().getNewCashDrawer();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              表达式 JavaPOSDevicesFactory.getInstance() 将返回 IBMJavaPOSDevicesFactoryNCRJavaPOSDevicesFactory 的实例,具体取决于读入的系统属性。请注意,通过更改属性文件中的外部系统属性 “jposfactory.classname”(即作为 String 的类名),NextGen 系统将使用不同的 JavaPOS 驱动程序系列。关于变化工厂的 Protected Variations 是通过数据驱动(读取属性文件)和反射编程设计实现的,使用 c.newInstance() 表达式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The expression JavaPOSDevicesFactory.getInstance() will return an instance of IBMJavaPOSDevicesFactory or NCRJavaPOSDevicesFactory, depending on the system property that is read in. Notice that by changing the external system property "jposfactory.classname" (which is the class name as a String) in a properties file, the NextGen system will use a different family of JavaPOS drivers. Protected Variations with respect to a changing factory has been achieved with a data-driven (reading a properties file) and reflective programming design, using the c.newInstance() expression.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              与工厂的交互将发生在 Register 中。为了实现低表示差距的目标,软件 Register(其名称暗示了整个 POS 终端)保留对 CashDrawer 等设备的引用是合理的。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Interaction with the factory will occur in a Register. By the goal of low representational gap, it is reasonable for the software Register (whose name is suggestive of the overall POS terminal) to hold a reference to devices such as CashDrawer. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private jpos.CashDrawer cashDrawer;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private jpos.CoinDispenser coinDispenser;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public Register()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 cashDrawer =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    JavaPOSDevicesFactory.getInstance().getNewCashDrawer();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              class Register
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private jpos.CashDrawer cashDrawer;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              private jpos.CoinDispenser coinDispenser;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              public Register()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 cashDrawer =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    JavaPOSDevicesFactory.getInstance().getNewCashDrawer();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                35.8. 使用多态性处理付款并自己动手

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                35.8. Handling Payments with Polymorphism and Do It Myself

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                应用多态性(和 Information Expert)的常见方法之一是在 Peter Coad 所说的 “Do It Myself” 策略或模式 [Coad95] 的上下文中。那是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                One of the common ways to apply polymorphism (and Information Expert) is in the context of what Peter Coad calls the "Do It Myself" strategy or pattern [Coad95]. That is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                自己动手

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do It Myself

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “我(软件对象)做那些通常对我所抽象的实际对象做的事情。”[Coad95]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                "I (a software object) do those things that are normally done to the actual object that I'm an abstraction of." [Coad95]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这是经典的面向对象的设计样式:圆形对象绘制自身,方形对象绘制自身,文本对象自身拼写检查,依此类推。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This is the classic object-oriented design style: Circle objects draw themselves, Square objects draw themselves, Text objects spell-check themselves, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,Text 对象本身进行拼写检查就是 Information Expert 的一个示例:包含与工作相关的信息的对象执行拼写检查(Dictionary 也是 Expert 的候选对象)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Notice that a Text object spell-checking itself is an example of Information Expert: The object that has the information related to the work does it (a Dictionary is also a candidate, by Expert).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do It Iself 和 Information Expert 通常会导致相同的选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do It Myself and Information Expert usually lead to the same choice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                同样,请注意,绘制自身的 CircleSquare 对象是多态性的示例:当相关替代项因类型而异时,将使用多态运算的责任分配给行为不同的类型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Similarly, notice that Circle and Square objects drawing themselves are examples of Polymorphism: When related alternatives vary by type, assign responsibility using polymorphic operations to the types for which the behavior varies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do It Myself 和 Polymorphism 通常会导致相同的选择。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Do It Myself and Polymorphism usually lead to the same choice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                然而,正如在 Pure Fabrication 讨论中所探讨的那样,由于耦合和内聚问题,它通常是禁忌的,相反,设计师使用纯制造,例如策略、工厂等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Yet, as was explored in the Pure Fabrication discussion, it is often contraindicated due to problems in coupling and cohesion, and instead, a designer uses pure fabrications such as strategies, factories, and the like.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                尽管如此,在适当的时候,“自己动手”之所以有吸引力,部分原因是它支持低代表性差距。处理付款的设计将通过 Do It Myself 和 Polymorphism 完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Nevertheless, when appropriate, Do It Myself is attractive in part because of its support for low representational gap. The design for handling payments will be accomplished with Do It Myself and Polymorphism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                此迭代的要求之一是处理多种付款类型,这实质上意味着处理授权和会计步骤。不同类型的付款以不同的方式授权:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                One of the requirements for this iteration is to handle multiple payment types, which essentially means to handle the authorization and accounting steps. Different kinds of payments are authorized in different ways:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 贷记付款和借记付款通过外部授权服务进行授权。两者都要求在欠下授权的金融机构的应收账款中记录应收账款分录。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Credit and debit payments are authorized with an external authorization service. Both require recording a receivable entry in accounts receivablemoney owing from the financial institution that does the authorization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 在一些商店(这在某些国家/地区是一种趋势)使用连接到 POS 终端的特殊纸质账单分析器进行现金支付,以检查假钞。其他商店不这样做。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Cash payments are authorized in some stores (it is a trend in some countries) using a special paper bill analyzer attached to the POS terminal that checks for counterfeit money. Other stores do not do this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 在一些商店中,支票付款是使用计算机化授权服务授权的。其他商店不进行授权检查。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Check payments are authorized in some stores using a computerized authorization service. Other stores do not do authorize checks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CreditPayments 以一种方式授权;CheckPayments 在另一个 .这是多态性的一个典型案例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                CreditPayments are authorized in one way; CheckPayments are authorized in another. This is a classic case for Polymorphism.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                因此,如图 35.17 所示,每个 Payment 子类都有自己的 authorize 方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Thus, as shown in Figure 35.17, each Payment subclass has its own authorize method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.17.具有多个 authorize 方法的经典多态性。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                例如,如图 35.18图 35.19 所示,Sale 实例化 CreditPaymentCheckPayment 并要求它授权自己。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For example, as illustrated in Figure 35.18 and Figure 35.19, a Sale instantiates a CreditPayment or CheckPayment and asks it to authorize itself..

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.18.创建 CreditPayment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.19.创建 CheckPayment。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                细粒度的类?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Fine-Grained Classes?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                考虑创建 CreditCard、DriversLicenseCheck 软件对象。我们的第一个冲动可能是简单地将他们持有的数据记录在相关的支付类中,并消除这种细粒度的类。但是,使用它们通常是一种更有利可图的策略;它们通常最终会提供有用的行为并且可以重用。例如,CreditCard 是告诉您其信用公司类型(Visa、MasterCard 等)的天生专家。此行为对于我们的应用程序来说是必需的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Consider the creation of the CreditCard, DriversLicense, and Check software objects. Our first impulse might be to record the data they hold simply in their related payment classes, and eliminate such fine-grained classes. However, it is usually a more profitable strategy to use them; they often end up providing useful behavior and being reusable. For example, the CreditCard is a natural Expert on telling you its credit company type (Visa, MasterCard, and so on). This behavior will turn out to be necessary for our application.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                信用支付授权

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Credit Payment Authorization

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                系统必须与外部信用授权服务通信,我们已经基于适配器创建了设计基础来支持这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The system must communicate with an external credit authorization service, and we have already created the basis of the design based on adapters to support this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                相关信用支付域信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                即将到来的设计的一些背景:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Some context for the upcoming design:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • POS 系统以多种方式与外部授权服务进行物理连接,包括电话线(必须拨打)和始终在线的宽带互联网连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • POS systems are physically connected with external authorization services in several ways, including phone lines (which must be dialed) and always-on broadband Internet connections.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 使用不同的应用程序级协议和相关数据格式,例如安全电子交易 (SET)。新的可能会流行起来,比如 XMLPay。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Different application-level protocols and associated data formats are used, such as Secure Electronic Transaction (SET). New ones may become popular, such as XMLPay.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 支付授权可以看作是常规的同步操作: POS 线程阻塞,等待远程服务的回复(在超时期限的限制内)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Payment authorization can be viewed as a regular synchronous operation: a POS thread blocks, waiting for a reply from the remote service (within the limits of a time-out period).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 所有支付授权协议都涉及发送唯一标识商店(使用“商家 ID”)和 POS 终端(使用“终端 ID”)的标识符。回复包括批准或拒绝代码以及唯一的交易 ID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • All payment authorization protocols involve sending identifiers uniquely identifying the store (with a "merchant ID"), and the POS terminal (with a "terminal ID"). A reply includes an approval or denial code, and a unique transaction ID.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 商店可以针对不同的信用卡类型使用不同的外部授权服务(一种用于 Visa,一种用于 MasterCard)。对于每项服务,商店都有不同的商家 ID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • A store may use different external authorization services for different credit card types (one for Visa, one for MasterCard). For each service, the store has a different merchant ID.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 信用公司类型可以从卡号中推断出来。例如,以 5 开头的数字是 MasterCard;以 4 开头的数字是 Visa。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The credit company type can be deduced from the card number. For example, numbers starting with 5 are MasterCard; numbers starting with 4 are Visa.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 适配器实现将保护系统的上层免受支付授权中的所有这些变化的影响。每个适配器都负责确保授权请求事务采用适当的格式,并与外部服务协作。正如在前面的迭代中所讨论的,ServicesFactory 负责提供适当的 ICreditAuthorizationServiceAdapter 实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • The adapter implementations will protect the upper layers of the system against all these variations in payment authorization. Each adapter is responsible for ensuring the authorization request transaction is in the appropriate format, and for collaborating with the external service. As discussed in a prior iteration, the ServicesFactory is responsible for delivering the appropriate ICreditAuthorizationServiceAdapter implementation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                设计方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.20 开始介绍满足这些细节和要求的带注释的设计。消息被注释以说明原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Figure 35.20 starts the presentation of an annotated design that satisfies these details and requirements. Messages are annotated to illustrate the reasoning.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.20.处理信用付款。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                一旦找到正确的 ICreditAuthorizationServiceAdapter,它就负责完成授权,如图 35.21 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once the correct ICreditAuthorizationServiceAdapter is found, it is given the responsibility for completing the authorization, as shown in Figure 35.21.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.21.完成授权。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                一旦 CreditPayment 获得回复(它已被 Polymorphism 和 Do It Myown 赋予处理其完成的责任),假设它被批准,它就会完成其任务,如图 35.22 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once a reply is obtained by CreditPayment (which has been given the responsibility for handling its completion by Polymorphism and Do It Myself), assuming it is approved, it completes its tasks, as shown in Figure 35.22.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 35.22.完成经批准的信用付款。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UML在此序列图中,可以看到一些对象是堆叠的。这是合法的,尽管很少有 CASE 工具支持它。它在 width 受到限制的发布中很有帮助。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UML Observe in this sequence diagram that some objects were stacked. This is legal, although few CASE tools support it. It is helpful in publishing, where width is constrained.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  35.9. 示例:垄断

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  35.9. Example: Monopoly

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  首先,让我们简要回顾一下迭代 3 中的新域规则和要求:如果玩家降落在一个财产方块(地块、铁路或公用事业)上,那么如果他们有足够的现金并且没有拥有它,他们就会购买它。如果它由其他玩家拥有,他们根据特定方块的规则支付租金。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  First, let's briefly review the new domain rules and requirements in iteration-3: If a player lands on a property square (a lot, railroad, or utility) then they buy it if they have enough cash and it's not owned. If it is owned by another player, they pay rent according to square-specific rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  让我们也回顾一下基本设计,如图 35.23图 35.24 所示。应用多态性;对于具有不同 landed-on 行为的每种 square,都有一个多态 landedOn 方法。当 Player 软件对象降落在 Square 上时,它会向其发送 landedOn 消息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Let's also review the essential design, as shown in Figure 35.23 and Figure 35.24. Polymorphism is applied; for each kind of square that has a different landed-on behavior, there is a polymorphic landedOn method. When a Player software object lands on a Square, it sends it a landedOn message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.23.多态 landedOn 设计策略的 DCD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.24.landedOn 设计策略的动态合作。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  现有设计展示了多态性的美感,以处理新的类似情况。对于此迭代,我们将简单地添加新的方形类型(LotSquare、RailRoadSquare、UtilitySquare)并添加更多多态 landedOn 方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The existing design shows off the beauty of polymorphism to handle new, similar cases. For this iteration, we will simply add new square types (LotSquare, RailRoadSquare, UtilitySquare) and add more polymorphic landedOn methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.26.尝试购买房产。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.27.支付房租。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.29.Monopoly 迭代 3 的部分 DCD。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  请注意,在图 35.25 中,所有的 PropertySquares 都有相同的 landedOn 行为,所以这个方法可以在超类中实现一次,并被 PropertySquare 的子类继承。每个子类唯一独有的行为是 rent 的计算;因此,根据多态性原理,每个子类中都有一个 getRent 多态操作(参见图 35.28)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Notice in Figure 35.25 that all the PropertySquares have identical landedOn behavior, so this method can be implemented once in the superclass and inherited by the subclasses of PropertySquare. The only behavior that is unique to each subclass is the calculation of the rent; thus by the Polymorphism principle, there is a getRent polymorphic operation in each subclass (see Figure 35.28).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.25.登陆 PropertySquare。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 35.28.多态 getRent 方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    35.10. 总结

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    35.10. Conclusion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这些案例研究的重点不是展示正确的解决方案没有一个最好的解决方案,我相信读者可以改进我所建议的。我真诚地希望证明,通过核心原则(如低耦合和模式的应用)来推理对象设计,而不是一个神秘的过程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The point of these case studies was not to show the correct solutionthere isn't a single best solution, and I'm sure readers can improve on what I've suggested. My sincere hope has been to demonstrate that doing object design can be reasoned through by core principles such as low coupling and the application of patterns, rather than being a mysterious process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    注意:图案 - 它是

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Caution: Pattern-itis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    本演示文稿在许多方面都使用了 GoF 设计模式。但有报道称,设计师在图案的创意狂潮中过度强行拟合图案——确实如此。我认为从中可以得出的结论是,模式需要在多个示例中进行研究才能被很好地消化。一种流行的学习工具是午餐时间或下班后的学习小组,参与者在其中分享他们已经看到或可以看到模式应用的方式,并讨论模式书的某个部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This presentation has used GoF design patterns at many points. But there have been reports of designers excessively force-fitting patterns in a creative frenzy of pattern-itis. I think a conclusion to draw from this is that patterns require study in multiple examples to be well-digested. A popular learning vehicle is a lunchtime or after-work study group in which participants share ways they have seen or could see the application of patterns, and discuss a section of a patterns book.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第 36 章.包装设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chapter 36. Package Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      如果你正在犁地,你更愿意使用哪块田地?两头强壮的牛还是 1024 只鸡?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      西摩·克雷

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If you were plowing a field, which would you rather use? Two strong oxen or 1024 chickens?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Seymour Cray

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 组织包以减少更改的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Organize packages to reduce the impact of changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 了解替代的 UML 包结构表示法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Know alternative UML package structure notation.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如果某个包 X 被开发团队广泛依赖,那么 X 非常不稳定是不可取的(经历许多新版本),因为它增加了对团队的影响,包括持续的版本重新同步和修复因 X 的变化而崩溃的依赖软件(版本抖动)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        If some package X is widely depended upon by the development team, it is undesirable for X to be very unstable (going through many new versions), since it increases the impact on the team in terms of constant version re-synchronization and fixing dependent software that breaks in response to changes in X (version thrashing).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这听起来很明显,但有时团队没有注意识别和稳定最依赖的包,最终经历了不必要的版本抖动,而没有意识到根本原因。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This soundsand isobvious, but sometimes a team does not pay attention to identifying and stabilizing the most depended-upon packages, and ends up experiencing more version thrashing than necessary, unaware of the underlying cause.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        本章以上一章对 layers 和 packages 的介绍为基础,为软件包的组织提出了更精细的启发式方法,以减少这些类型的更改影响。目标是创建强大的物理封装设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This chapter builds on previous chapter's introduction to layers and packages, by suggesting more fine-grained heuristics for the organization of packages, to reduce these kinds of change impact. The goal is to create a robust physical package design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        由于 C++ 中高度敏感的编译和链接依赖项,人们在 C++ 中比在 Java 中更快地感受到脆弱的依赖敏感包组织的痛苦;一个类中的更改可能会产生强烈的传递依赖项影响,从而导致重新编译多个类并重新链接。[1] 因此,这些建议对 C++ 项目特别有用,对 Java 或 C#(例如)项目则适中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        One feels the pain of fragile dependency-sensitive package organization much more quickly in C++ than in Java because of the hyper-sensitive compile and link dependencies in C++; a change in one class can have a strong transitive dependency impact leading to recompilation of many classes, and re-linking.[1] Therefore, these suggestions are especially helpful for C++ projects and moderately so for Java or C# (as examples) projects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1]在 C++ 中,包可能实现为命名空间,但更有可能的是,这意味着将源代码组织到单独的物理目录中,每个“包”对应一个目录。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] In C++ the packages may be realized as namespaces, but more likely it means the organization of the source code into separate physical directoriesone for each "package."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Robert Martin [Martin95] 致力于 C++ 应用程序的物理设计和打包,他的有用工作影响了以下一些准则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The useful work of Robert Martin [Martin95], who has grappled with physical design and packaging of C++ applications, influenced some of the following guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        实现模型中的源代码物理设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Source Code Physical Design in the Implementation Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此问题是物理设计的一个方面,即用于源代码打包的 UP 实现模型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This issue is an aspect of physical designthe UP Implementation Model for source code packaging.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        虽然只是在白板或 CASE 工具上绘制包设计图,但我们可以任意地将类型放置在任何功能上内聚的包中,而不会产生影响。但是在源代码物理设计过程中,如果有许多开发人员共享一个公共代码库,那么当这些包发生更改时,将类型组织成物理发布单元作为 Java 或 C++“包”,我们的选择将影响开发人员的影响程度。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        While simply diagramming a package design on a whiteboard or CASE tool, we can arbitrarily place types in any functionally cohesive package without impact. But during source code physical designthe organization of types into physical units of release as Java or C++ "packages"our choices will influence the degree of developer impact when changes in those packages occur, if there are many developers sharing a common code base.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          36.1. 软件包组织准则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          36.1. Package Organization Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:打包功能内聚的垂直和水平切片

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Package Functionally Cohesive Vertical and Horizontal Slices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          基本的 “直观” 原则是基于功能内聚类型(类和接口)的模块化,这些类型在参与共同目标、服务、协作、策略和功能方面密切相关。例如,NextGen Pricing 包中的所有类型都与产品定价有关。NextGen 设计中的 layers 和 packages 按功能组进行组织。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The basic "intuitive" principle is modularization based on functional cohesiontypes (classes and interfaces) are grouped together that are strongly related in terms of their participation in a common purpose, service, collaborations, policy, and function. For example, all the types in the NextGen Pricing package are related to product pricing. The layers and packages in the NextGen design are organized by functional groups.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          除了通常对按功能分组的足够非正式的猜测(“我认为类 SalesLineItem 属于 Sales”)之外,功能分组的另一个线索是具有强内部耦合和较弱的群集外耦合的类型群集。例如,Register 与 Sale 具有很强的耦合,而 Sale 与 SalesLineItem 具有很强的耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In addition to the usually sufficient informal guesswork on grouping by function ("I think class SalesLineItem belongs in Sales") another clue to functional grouping is a cluster of types with strong internal coupling and weaker extra-cluster coupling. For example, Register has a strong coupling to Sale, which has a strong coupling to SalesLineItem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          内部包耦合或关系内聚是可以量化的,尽管这种形式化分析很少具有实际必要性。对于好奇的人来说,一个衡量标准是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Internal package coupling, or relational cohesion, can be quantified, although such formal analysis is rarely of practical necessity. For the curious, one measure is:



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          其中 NumberOfInternalRelations 包括包中类型之间的属性和参数关系、继承和接口实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Where NumberOfInternalRelations includes attribute and parameter relations, inheritance, and interface implementations between types in the package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          具有 12 个内部关系的 6 种类型的包的 RC=2。具有 3 个类型内关系的 6 个类型的包的 RC=0.5。数字越高,表示包的内聚性或相关性越高。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A package of 6 types with 12 internal relations has RC=2. A package of 6 types with 3 intra-type relations has RC=0.5. Higher numbers suggest more cohesion or relatedness for the package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,此度量值不太适用于主要包含接口的包;它对于包含一些 implementation classes 的 package 最有用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that this measure is less applicable to packages of mostly interfaces; it is most useful for packages that contain some implementation classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          非常低的 RC 值表明:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A very low RC value suggests either:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 该包包含不相关的事物,并且没有很好地分解。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The package contains unrelated things and is not factored well.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 包里有不相关的东西,设计师故意不在乎。这在不同服务的实用程序包(例如 java.util)中很常见,其中高或低 RC 并不重要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • The package contains unrelated things and the designer deliberately does not care. This is common with utility packages of disparate services (e.g., java.util), where high or low RC is not important.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 它包含一个或多个具有高 RC 的子集集群,但总体上不包含。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • It contains one or more subset clusters with high RC, but overall does not.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:打包一系列接口

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Package a Family of Interfaces

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将一系列功能相关的接口放在一个单独的包中,与 implementation classes 分开。Java 技术 EJB 包 javax.ejb 就是一个示例:它是一个至少包含 12 个接口的包;implementations 位于单独的 packages 中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Place a family of functionally related interfaces in a separate packageseparate from implementation classes. The Java technologies EJB package javax.ejb is an example: It is a package of at least twelve interfaces; implementations are in separate packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:按 Work 和 Unstable 类的集群打包

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Package by Work and by Clusters of Unstable Classes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          此讨论的上下文是 package 通常是开发工作和发布的基本单元。只处理和发布一个类的情况不太常见。除非包很大或非常复杂,否则开发人员通常负责其中的所有类型的包。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The context for this discussion is that packages are usually the basic unit of development work and of release. It is less common to work on and release just one class. Unless a package is massive or very complex, a developer is often responsible for all the types within it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          假设 1) 有一个现有的大包 P1,其中包含 30 个类,并且 2) 有一个工作趋势,即 10 个类的特定子集(C1 到 C10)会定期修改和重新发布。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Suppose 1) there is an existing large package P1 with thirty classes, and 2) there is a work trend that a particular subset of ten classes (C1 through C10) is regularly modified and re-released.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在这种情况下,将 P1 重构为 P1-a 和 P1-b,其中 P1-b 包含十个经常使用的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In this case, refactor P1 into P1-a and P1-b, where P1-b contains the ten frequently worked on classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因此,包已被重构为更稳定和更不稳定的子集,或者更一般地说,重构为与 work 相关的组。也就是说,如果包中的大多数类型一起处理,则它是一个有用的分组。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Thus, the package has been refactored into more stable and less stable subsets, or more generally, into groups related to work. That is, if most types in a package are worked on together, then it is a useful grouping.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          理想情况下,对 P1-b 的依赖程度低于对 P1-a 的依赖程度,并且通过将这个不稳定的部分分解到一个单独的包中,受 P1-b 新版本影响的开发者不会像重新发布更大的原始包 P1 那样多。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Ideally, fewer developers have a dependency on P1-b than on P1-a, and by factoring out this unstable part to a separate package, not as many developers are affected by new releases of P1-b as by re-releasing the larger original package P1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,此重构是对新兴工作趋势的响应。在非常早期的迭代中,很难推测性地确定一个好的包结构。它在细化迭代中逐步发展,细化阶段的目标应该是(因为它在架构上很重要)通过细化完成来稳定大部分包结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that this refactoring is in reaction to an emerging work trend. It is difficult to speculatively identify a good package structure in very early iterations. It incrementally evolves over the elaboration iterations, and it should be a goal of the elaboration phase (because it is architecturally significant) to have the majority of the package structure stabilized by elaboration completion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          该指南说明了基本策略: 减少对不稳定软件包的广泛依赖

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This guideline illustrates the basic strategy: Reduce widespread dependency on unstable packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          准则:最负责任的是最稳定的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Most Responsible Are Most Stable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果最负责任(依赖的)包不稳定,则更有可能产生广泛的更改依赖项影响。在极端情况下,如果广泛使用的实用程序包(如 com.foo.util)频繁更改,则许多事情都可能中断。因此,图 36.1 说明了适当的依赖关系结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If the most responsible (depended-on) packages are unstable, there is a greater chance of widespread change dependency impact. As an extreme case, if a widely used utility package such as com.foo.util changed frequently, many things could break. Therefore, Figure 36.1 illustrates an appropriate dependency structure.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.1.更负责任的软件包应该更稳定。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          从视觉上看,此图中较低的包应该是最稳定的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Visually, the lower packages in this diagram should be the most stable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有多种方法可以提高包的稳定性:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          There are different ways to increase stability in a package:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 它仅包含或主要包含接口和抽象类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 例如,java.sql 包含 8 个接口和 6 个类,这些类大多是简单、稳定的类型,例如 TimeDate

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • It contains only or mostly interfaces and abstract classes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • For example, java.sql contains eight interfaces and six classes, and the classes are mostly simple, stable types such as Time and Date.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 它不依赖于其他 package (它是独立的),或者它依赖于其他非常稳定的 package,或者它封装了它的依赖项,以便依赖者不受影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 例如,com.foo.nextgen.domain.posruleengine 将其规则引擎实现隐藏在单个 Facade 对象后面。即使实现发生更改,依赖包也不会受到影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • It has no dependencies on other packages (it is independent), or it depends on other very stable packages, or it encapsulates its dependencies such that dependents are not affected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • For example, com.foo.nextgen.domain.posruleengine hides its rule engine implementation behind a single facade object. Even if the implementation changes, dependent packages are not affected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 它包含相对稳定的代码,因为它在发布前经过了很好的锻炼和完善。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 例如,java.util.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • It contains relatively stable code because it was well-exercised and refined before release.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • For example, java.util.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 它被强制要求有一个缓慢的更改时间表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 例如,java.lang(Java 库中的核心包)根本不允许频繁更改。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • It is mandated to have a slow change schedule.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • For example, java.lang, the core package in the Java libraries, is simply not allowed to change frequently.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:分解出独立类型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Factor out Independent Types

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将可以独立使用或在不同上下文中使用的类型组织到单独的包中。如果不仔细考虑,按通用功能分组可能无法在包的分解中提供正确的粒度级别。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Organize types that can be used independently or in different contexts into separate packages. Without careful consideration, grouping by common functionality may not provide the right level of granularity in the factoring of packages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          例如,假设在一个包 com.foo.service.persistence 中定义了持久性服务的子系统。在这个包中,有两个非常通用的工具/帮助程序类 JDBCUtililitiesSQLCommand。如果这些是与 JDBC(Java 的关系数据库访问服务)一起使用的通用实用程序,那么在开发人员使用 JDBC 的任何场合,它们可以独立于持久化子系统使用。因此,最好将这些类型迁移到单独的包中,例如 com.foo.util.jdbc图 36.2 说明了这一点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          For example, suppose that a subsystem for persistence services has been defined in one package com.foo.service.persistence. In this package are two very general utility/helper classes JDBCUtililities and SQLCommand. If these are general utilities for working with JDBC (Java's services for relational database access), then they can be used independently of the persistence subsystem, for any occasion when the developer is using JDBC. Therefore, it is better to migrate these types into a separate package, such as com.foo.util.jdbc. Figure 36.2 illustrates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.2.分解出独立类型。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:使用 Factory 减少对 Concrete 包的依赖

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: Use Factories to Reduce Dependency on Concrete Packages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          提高包稳定性的一种方法是减少它对其他包中具体类的依赖。图 36.3 说明了 “之前” 的情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          One way to increase package stability is to reduce its dependency on concrete classes in other packages. Figure 36.3 illustrates the "before" situation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.3.由于创建而直接连接到混凝土包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          假设 RegisterPaymentMapper(将 payment 对象映射到关系数据库或从关系数据库映射的类)都从 Payments 包创建 CreditPayment 的实例。提高 SalesPersistence 包长期稳定性的一种机制是停止显式创建在其他包中定义的具体类(Payments 中的 CreditPayment)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Suppose that both Register and PaymentMapper (a class that maps payment objects to/from a relational database) create instances of CreditPayment from package Payments. One mechanism to increase the long-term stability of the Sales and Persistence packages is to stop explicitly creating concrete classes defined in other packages (CreditPayment in Payments).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          我们可以通过使用创建实例的工厂对象来减少与这个具体包的耦合,但其 create 方法返回以接口而不是类声明的对象。参见图 36.4

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We can reduce the coupling to this concrete package by using a factory object that creates the instances, but whose create methods return objects declared in terms of interfaces rather than classes. See Figure 36.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.4.通过使用 Factory 对象减少了与具体包的耦合。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          域对象工厂模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          使用带有接口的域对象工厂来创建所有域对象是一种常见的设计习惯。我在设计文献中见过它被非正式地称为 Domain Object Factory 模式,但不知道有没有已发布的参考资料。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The use of domain object factories with interfaces for the creation of all domain objects is a common design idiom. I have seen it mentioned informally in design literature as the Domain Object Factory pattern, but don't know of a published reference.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          指南:封装中没有循环

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Guideline: No Cycles in Packages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果一组 package 具有循环依赖性,那么它们可能需要被视为一个更大的 release unit。这是不可取的,因为发布较大的 package(或 package aggregates)会增加影响某些内容的可能性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If a group of packages have cyclic dependency, then they may need to be treated as one larger package in terms of a release unit. This is undesirable because releasing larger packages (or package aggregates) increases the likelihood of affecting something.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有两种解决方案:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          There are two solutions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. 将参与 cycle 的类型分解到一个新的更小的包中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. Factor out the types participating in the cycle into a new smaller package.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. 用接口打破这个循环。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. Break the cycle with an interface.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          使用接口打破循环的步骤是:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The steps to break the cycle with an interface are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在其中一个包中重新定义 depended-on 类以实现新接口。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在新包中定义新接口。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          重新定义依赖类型以依赖于新包中的接口,而不是原始类。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.5 说明了这种策略。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Figure 36.5 illustrates this strategy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 36.5.打破循环依赖。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            36.2. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            36.2. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            毫不奇怪,改进包设计以减少依赖项影响的大部分详细工作都来自 C++ 社区,尽管这些原则适用于其他语言。Martin 的 Designing Object-Oriented C++ Applications Using the Booch Method [Martin95] 提供了很好的覆盖范围,大规模 C++ 软件设计 [Lakos96] 也提供了很好的覆盖范围。Java 2 Performance and Idiom Guide [GL99] 中也介绍了该主题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Most of the detailed worknot surprisinglyon improving package design to reduce dependency impact comes from the C++ community, although the principles apply to other languages. Martin's Designing Object-Oriented C++ Applications Using the Booch Method [Martin95] provides good coverage, as does Large-Scale C++ Software Design [Lakos96]. The subject is also introduced in Java 2 Performance and Idiom Guide [GL99].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              第 37 章.UML 部署和组件图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Chapter 37. UML Deployment and Component Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              说我偏执,但在这条评论里发现 '/*' 让我很怀疑。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              MPW C 编译器警告

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Call me paranoid but finding '/*' inside this comment makes me suspicious.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              An MPW C compiler warning

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 总结 UML 部署和组件图表示法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Summarize UML deployment and component diagram notation.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                37.1. 部署图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                37.1. Deployment Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                部署图显示了将具体的软件工件(比如可执行文件)分配给计算节点(具有处理服务的东西)的过程。它显示了软件元素到物理体系结构的部署以及物理元素之间的通信(通常在网络上)。参见图 37.1。部署图对于传达物理或部署架构很有用,例如,在 UP 软件架构文档中,从第 656 页开始讨论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A deployment diagram shows the assignment of concrete software artifacts (such as executable files) to computational nodes (something with processing services). It shows the deployment of software elements to the physical architecture and the communication (usually on a network) between physical elements. See Figure 37.1. Deployment diagrams are useful to communicate the physical or deployment architecture, for example, in the UP Software Architecture Document, discussed starting on p. 656.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 37.1.部署图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                部署图的基本元素是一个节点,有两种类型:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The basic element of a deployment diagram is a node, of two types:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 设备节点(或设备 一种物理(例如,数字电子)计算资源,具有处理和内存服务,用于执行软件,例如典型的计算机或移动电话。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • device node (or device) A physical (e.g., digital electronic) computing resource with processing and memory services to execute software, such as a typical computer or a mobile phone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 执行环境节点 (EEN) 这是在外部节点(如计算机)中运行的软件计算资源,它本身提供托管和执行其他可执行软件元素的服务。例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 操作系统 (OS) 是托管和执行程序的软件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 虚拟机(VM,例如 Java 或 .NET VM)托管和执行程序

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 数据库引擎(如 PostgreSQL)接收并执行 SQL 程序请求,并托管/执行内部存储过程(用 Java 或专有语言编写)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Web 浏览器托管并执行 JavaScript、Java 小程序、Flash 和其他可执行技术

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 工作流引擎

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 一个 servlet 容器EJB 容器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • execution environment node (EEN) This is a software computing resource that runs within an outer node (such as a computer) and which itself provides a service to host and execute other executable software elements. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • an operating system (OS) is software that hosts and executes programs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a virtual machine (VM, such as the Java or .NET VM) hosts and executes programs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a database engine (such as PostgreSQL) receives SQL program requests and executes them, and hosts/executes internal stored procedures (written in Java or a proprietary language)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a Web browser hosts and executes JavaScript, Java applets, Flash, and other executable technologies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a workflow engine

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • a servlet container or EJB container

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                正如 UML 规范所暗示的那样,许多节点类型可能显示构造型,例如 “server”、“OS”、“database” 或 “browser”,但这些不是官方预定义的 UML 构造型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As the UML specification suggests, many node types may show stereotypes, such as «server», «OS», «database», or «browser», but these are not official predefined UML stereotypes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                请注意,设备节点或 EEN 可能包含另一个 EEN。例如,计算机内操作系统内的虚拟机。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Note that a device node or EEN may contain another EEN. For example, a virtual machine within an OS within a computer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                特定的 EEN 可以是隐含的,也可以是不显示的,或者使用 UML 属性字符串非正式地表示;例如,{OS=Linux}。例如,将 OS EEN 显示为显式节点可能没有价值。图 37.1 以 OS 为例显示了替代样式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A particular EEN can be implied, or not shown, or indicated informally with a UML property string; for example, {OS=Linux}. For example, there may not be value in showing the OS EEN as an explicit node. Figure 37.1 shows alternate styles, using the OS as an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                节点之间的正常连接是一条通信路径,可以标有协议。这些通常表示网络连接。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The normal connection between nodes is a communication path, which may be labeled with the protocol. These usually indicate the network connections.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                节点可以包含并向工件显示具体物理元素,通常是文件。这包括 JAR、程序集、.exe 文件和脚本等可执行文件。它还包括 XML、HTML 等数据文件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A node may contain and show an artifacta concrete physical element, usually a file. This includes executables such as JARs, assemblies, .exe files, and scripts. It also includes data files such as XML, HTML, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                部署图通常显示一组示例实例(而不是类)。例如,运行 Linux OS 实例的服务器计算机的实例。通常在 UML 中,具体实例在其名称下方显示下划线,没有下划线表示类而不是实例。请注意,此规则的一个主要例外是交互图中的实例,其中表示生命线框中实例的事物名称没有下划线。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A deployment diagram usually shows an example set of instances (rather than classes). For example, an instance of a server computer running an instance of the Linux OS. Generally in the UML, concrete instances are shown with an underline under their name, and the absence of an underline signifies a class rather than an instance. Note that a major exception to this rule is instances in interaction diagramsthere, the names of things signifying instances in lifeline boxes are not underlined.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                无论如何,在部署图中,您通常会看到对象的名称带有下划线,以指示实例。但是,UML 规范规定,对于部署图,可以省略和假设下划线。因此,您可以看到两种样式的示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In any event, in deployment diagrams, you will usually see the objects with their name underlined, to indicate instances. However, the UML specification states that for deployment diagrams, the underlining may be omitted and assumed. Therefore, you can see examples in both styles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  37.2. 组件图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  37.2. Component Diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  组件在 UML 中是一个稍微模糊的概念,因为类和组件都可用于对同一事物进行建模。例如,引用 Rumbaugh(UML 创始人之一):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Components are a slightly fuzzy concept in the UML, because both classes and components can be used to model the same thing. For example, to quote Rumbaugh (one of the UML founders):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  结构化类和组件之间的区别有些模糊,更多的是意图问题,而不是严格的语义问题。[RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The distinction between a structured class and a component is somewhat vague and more a matter of intent than firm semantics. [RJB04]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  引用 UML 规范 [OMG03b]:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  And to quote the UML specification [OMG03b]:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  组件 表示系统的模块化部分,该部分封装了其内容,并且其表现形式在其环境中是可替换的。组件根据提供的接口和必需的接口定义其行为。因此,组件充当一种类型,其一致性由这些提供和必需的接口定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A component represents a modular part of a system that encapsulates its contents and whose manifestation is replaceable within its environment. A component defines its behavior in terms of provided and required interfaces. As such, a component serves as a type, whose conformance is defined by these provided and required interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  同样,这个想法可以用一个常规的 UML 类及其提供的和必需的接口来建模。回想一下,UML 类可用于对任何级别的软件元素进行建模,从整个系统到子系统再到小型实用程序对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Again, this idea can be modeled with a regular UML class and its provided and required interfaces. Recall that a UML class can be used to model any level of software element, from an entire system to subsystem to small utility object.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  但是,当使用 UML 组件时,建模和设计意图是强调 1) 接口很重要,以及 2) 它是模块化的、自包含的和可替换的。第二点意味着组件往往很少或根本不依赖于其他外部元素(可能除了标准核心库);它是一个相对独立的模块。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  But when one uses a UML component, the modeling and design intent is to emphasize 1) that the interfaces are important, and 2) it is modular, self-contained and replaceable. The second point implies that a component tends to have little or no dependency on other external elements (except perhaps standard core libraries); it is a relatively stand-alone module.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML 组件是设计级的透视图;它们不存在于 Concrete Software 透视图中,但映射到 Concrete 工件,例如一组文件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  UML components are a design-level perspective; they don't exist in the concrete software perspective, but map to concrete artifacts such as a set of files.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  软件组件建模的一个很好的类比是家庭娱乐系统;我们希望能够轻松更换 DVD 播放器或扬声器。它们是模块化的、独立的、可更换的,并通过标准接口工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A good analogy for software component modeling is a home entertainment system; we expect to be able to easily replace the DVD player or speakers. They are modular, self-contained, replaceable, and work via standard interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  例如,在大粒度级别,可以将 SQL 数据库引擎建模为组件;任何理解相同版本的 SQL 并支持相同事务语义的数据库都可以被替换。更精细地说,可以在系统中使用或替换任何实现标准 Java 消息服务 API 的解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For example, at a large-grained level, a SQL database engine can be modeled as a component; any database that understands the same version of SQL and supports the same transaction semantics can be substituted. At a finer level, any solution that implements the standard Java Message Service API can be used or replaced in a system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  由于基于零部件的建模的重点是可更换零件(可能是为了升级以获得更好的非功能质量,例如性能),因此对相对较大的元件进行零部件建模是一个一般准则,因为很难考虑或设计许多小型、细粒度的可更换零件。图 37.2 说明了基本符号。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Since the emphasis of component-based modeling is replaceable parts (perhaps to upgrade for better non-functional qualities, such as performance), it's a general guideline to do component modeling for relatively large-scale elements, because it is difficult to think about or design for many small, fine-grained replaceable parts. Figure 37.2 illustrates the essential notation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 37.2.UML 组件。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  基于组件的专用建模和开发主题是一个大型的专业主题,超出了 OOA/D 简介的范围。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The topic of dedicated component-based modeling and development is a large, specialized subject, outside of the scope of this introduction to OOA/D.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    第 38 章.使用模式设计持久性框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Chapter 38. Designing a Persistence Framework with Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    大多数专家都认为,世界最有可能被摧毁的方式是偶然。这就是我们的切入点;我们是计算机专业人士。我们制造事故。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    纳撒尼尔·博伦斯坦

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Nathaniel Borenstein

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 使用 Template Method、State 和 Command 模式设计框架的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Design part of a framework with the Template Method, State, and Command patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 在对象关系 (O-R) 映射中引入问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Introduce issues in object-relational (O-R) mapping.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 使用 Virtual Proxies 实现延迟具体化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Implement lazy materialization with Virtual Proxies.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      本章的重点实际上并不是设计一个持久化框架,而是更广泛地介绍关键的 OO 框架设计原则和模式,使用持久化作为一个有趣的案例研究。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The point of this chapter is not actually the design of a persistence framework, but, more generally, to introduce key OO framework design principles and patterns, using persistence as an interesting case study.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      NextGen 应用程序最需要将信息存储在持久存储机制中,例如关系数据库 (RDB)。本章探讨了用于存储持久对象的框架的设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The NextGen applicationlike mostrequires storing and retrieving information in a persistent storage mechanism, such as a relational database (RDB). This chapter explores the design of a framework for storing persistent objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      谨慎!不要在家里尝试这个!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Caution! Don't Try This at Home!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      有优秀的免费、健壮、工业级的开源持久化框架,因此很少需要自己创建一个。例如,Hibernate 在 Java 域 (www.hibernate.org) 中得到了非常广泛的使用。它解决了对象关系映射、性能、事务支持等方面的大部分或全部问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There are excellent free, robust, industrial-strength open source persistence frameworks, and thus seldom a need to create one yourself. For example, Hibernate is very widely used in the Java domain (www.hibernate.org). It solves most or all problems in object-relational mapping, performance, transaction support, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      介绍此持久化框架是为了介绍应用于常见且问题丰富的领域的框架设计。不建议将其用于 industrial persistence 服务。至少对于 Java 技术,没有必要自己创建一个。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This persistence framework is presented to introduce framework design applied to a common and problem-rich domain. It is not recommended for an industrial persistence service. At least for Java technologies, there is no need to create one yourself.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.1. 问题:持久对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.1. The Problem: Persistent Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        假设在 NextGen 应用程序中,ProductDescription 数据驻留在关系数据库中。在应用程序使用期间,必须将其引入本地内存。持久性对象是需要持久性存储的对象,例如 ProductDescription 实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Assume that in the NextGen application, ProductDescription data resides in a relational database. It must be brought into local memory during application use. Persistent objects are those that require persistent storage, such as ProductDescription instances.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        存储机制和持久对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Storage Mechanisms and Persistent Objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象数据库如果使用对象数据库来存储和检索对象,则不需要额外的自定义或第三方持久性服务。这是使用它的几个景点之一。但是,它们相对罕见。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Object databases If an object database is used to store and retrieve objects, no additional custom or third-party persistence services are required. This is one of several attractions for its use. However, they are relatively rare.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        关系数据库由于 RDB 的普遍存在,因此通常需要使用它们,而不是更多的 OO 自然对象数据库。如果是这种情况,则由于面向记录和面向对象的数据表示之间的不匹配,会出现许多问题;这些问题将在后面探讨。需要特殊的 O-R 映射服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Relational databases Because of the prevalence of RDBs, their use is often required, rather than the more OO-natural object databases. If this is the case, a number of problems arise due to the mismatch between record-oriented and object-oriented representations of data; these problems are explored later. A special O-R mapping service is required.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        其他除了 RDB 之外,有时还需要以其他存储机制或格式存储对象,例如平面文件、XML 结构、Palm OS PDB 文件、分层数据库等。与关系数据库一样,对象和这些非面向对象的格式之间存在表示不匹配。与 RDB 一样,需要特殊服务才能使它们与对象一起工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Other In addition to RDBs, it is sometimes desirable to store objects in other storage mechanisms or formats, such as flat files, XML structures, Palm OS PDB files, hierarchical databases, and so on. As with relational databases, a representation mismatch exists between objects and these non-object-oriented formats. And as with RDBs, special services are required to make them work with objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.2. 解决方案:来自 Persistence 框架的 Persistence 服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.2. The Solution: A Persistence Service from a Persistence Framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          持久性框架是一组通用、可重用且可扩展的类型,可提供支持持久性对象的功能。持久化服务(或子系统)实际上提供服务,并将使用持久化框架创建。通常编写持久性服务以使用 RDB,在这种情况下,它也称为 O-R 映射服务。通常,持久性服务必须将对象转换为记录(或某些其他形式的结构化数据,如 XML)并将其保存在数据库中,并在从数据库中检索时将记录转换为对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A persistence framework is a general-purpose, reusable, and extendable set of types that provides functionality to support persistent objects. A persistence service (or subsystem) actually provides the service, and will be created with a persistence framework. A persistence service is usually written to work with RDBs, in which case it is also called an O-R mapping service. Typically, a persistence service must translate objects into records (or some other form of structured data such as XML) and save them in a database, and translate records into objects when retrieving from a database.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          就 NextGen 应用程序的分层架构而言,持久化服务是技术服务层中的一个子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In terms of the layered architecture of the NextGen application, a persistence service is a subsystem within the technical services layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.3. 框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.3. Frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            尽管存在过度简化的风险,框架是一组用于相关函数的可扩展对象。典型的示例是 GUI 框架,例如 Java 的 Swing 框架。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            At the risk of oversimplification, a framework is an extendable set of objects for related functions. The quintessential example is a GUI framework, such as Java's Swing framework.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            框架的标志性品质是它为核心和不变功能提供实现,并包括允许开发人员插入可变功能或扩展功能的机制。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The signature quality of a framework is that it provides an implementation for the core and unvarying functions, and includes a mechanism to allow a developer to plug in the varying functions, or to extend the functions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,Java 的 Swing GUI 框架为核心 GUI 功能提供了许多类和接口。开发人员可以通过从 Swing 类进行子类化并覆盖某些方法来添加专用 widget。开发人员还可以通过基于 Observer 模式注册侦听器或订阅者,将不同的事件响应行为插入到预定义的小部件类(例如 JButton)中。这是一个框架。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, Java's Swing GUI framework provides many classes and interfaces for core GUI functions. Developers can add specialized widgets by subclassing from the Swing classes and overriding certain methods. Developers can also plug in varying event response behavior to predefined widget classes (such as JButton) by registering listeners or subscribers based on the Observer pattern. That's a framework.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            通常,框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In general, a framework:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 是一组内聚的接口和类,它们协作为逻辑子系统的核心、不变部分提供服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Is a cohesive set of interfaces and classes that collaborate to provide services for the core, unvarying part of a logical subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 包含具体(尤其是)抽象类,这些类定义要遵循的接口、要参与的对象交互以及其他不变量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Contains concrete (and especially) abstract classes that define interfaces to conform to, object interactions to participate in, and other invariants.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 通常(但不一定)要求框架用户定义现有框架类的子类,以使用、自定义和扩展框架服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Usually (but not necessarily) requires the framework user to define subclasses of existing framework classes to make use of, customize, and extend the framework services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 具有可能同时包含抽象方法和具体方法的抽象类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Has abstract classes that may contain both abstract and concrete methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 依赖于好莱坞原则不要打电话给我们,我们会打电话给您”。这意味着用户定义的类(例如,新的子类)将接收来自预定义框架类的消息。这些通常是通过实现 superclass 抽象方法来处理的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Relies on the Hollywood Principle "Don't call us, we'll call you." This means that the user-defined classes (for example, new subclasses) will receive messages from the predefined framework classes. These are usually handled by implementing superclass abstract methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            以下持久性框架示例将演示这些原则。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The following persistence framework example will demonstrate these principles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            框架是可重用的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Frameworks Are Reusable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            框架提供了高度的重用性,比单个类要多得多。因此,如果一个组织对提高其软件重用程度感兴趣(谁不感兴趣呢),那么它应该强调框架的创建。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Frameworks offer a high degree of reusemuch more so than individual classes. Consequently, if an organization is interested (and who isn't?) in increasing its degree of software reuse, then it should emphasize the creation of frameworks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.4. 持久化服务和框架的要求

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.4. Requirements for the Persistence Service and Framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              对于 NextGen POS 应用程序,我们需要使用持久化框架构建持久化服务(该框架也可用于创建其他持久化服务)。我们将框架称为 PFW (Persistence Framework)。PFW 是一个简化的框架一个成熟的、工业级的持久性框架,不在本介绍的讨论范围之内。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For the NextGen POS application, we need a persistence service to be built with a persistence framework (which could be used to also create other persistence services). Let's call the framework PFW (Persistence Framework). PFW is a simplified frameworka full-blown, industrial-strength persistence framework is outside the scope of this introduction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              框架应提供如下功能:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The framework should provide functions such as:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 在持久存储机制中存储和检索对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • store and retrieve objects in a persistent storage mechanism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 提交回滚事务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • commit and rollback transactions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              设计应可扩展以支持不同的存储机制和格式,例如 RDB、平面文件中的记录或文件中的 XML。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The design should be extendable to support different storage mechanisms and formats, such as RDBs, records in flat files, or XML in files.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.5. 关键思想

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.5. Key Ideas

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                以下关键思想将在后续部分中探讨:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The following key ideas will be explored in subsequent sections:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 映射类与其持久存储 (例如,数据库中的表) 之间以及对象属性与记录中的字段 (列) 之间必须存在某种映射。也就是说,两个 Schema 之间必须存在 Schema 映射

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Mapping There must be some mapping between a class and its persistent store (for example, a table in a database), and between object attributes and the fields (columns) in a record. That is, there must be a schema mapping between the two schemas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 对象标识为了轻松地将记录与对象关联,并确保没有不适当的重复项,记录和对象具有唯一的对象标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Object identity To easily relate records to objects, and to ensure there are no inappropriate duplicates, records and objects have a unique object identifier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 数据库映射器Pure Fabrication 数据库映射器负责物质化和非物质化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Database mapper A Pure Fabrication database mapper is responsible for materialization and dematerialization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 物化和非物质化具体化是指将数据(例如,记录)的非对象表示形式从持久存储转换为对象的操作。非物质化是相反的活动(也称为钝化)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Materialization and dematerialization Materialization is the act of transforming a non-object representation of data (for example, records) from a persistent store into objects. Dematerialization is the opposite activity (also known as passivation).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 缓存持久性服务缓存具体化对象以提高性能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Caches Persistence services cache materialized objects for performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 对象的事务状态根据对象与当前事务的关系了解对象的状态非常有用。例如,了解哪些对象已被修改 (脏) 非常有用,这样就可以确定是否需要将它们保存回其持久存储。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Transaction state of object It is useful to know the state of objects in terms of their relationship to the current transaction. For example, it is useful to know which objects have been modified (are dirty) so that it is possible to determine if they need to be saved back to their persistent store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 交易操作提交和回滚操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Transaction operations Commit and rollback operations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 延迟具体化并非所有对象都会立即实现;特定实例仅在需要时按需具体化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Lazy materialization Not all objects are materialized at once; a particular instance is only materialized on-demand, when needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 虚拟代理惰性具体化可以使用称为虚拟代理的智能引用来实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Virtual proxies Lazy materialization can be implemented using a smart reference known as a virtual proxy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  38.6. 模式:将对象表示为 table

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  38.6. Pattern: Representing Objects as Tables

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如何将对象映射到记录或关系数据库架构?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  How do you map an object to a record or relational database schema?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  将对象表示为表 模式 [BW96] 建议在 RDB 中为每个持久对象类定义一个表。包含原始数据类型(数字、字符串、布尔值等)的对象属性映射到列。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Representing Objects as Tables pattern [BW96] proposes defining a table in an RDB for each persistent object class. Object attributes containing primitive data types (number, string, boolean, and so on) map to columns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如果对象仅具有原始数据类型的属性,则映射非常简单。但正如我们将看到的,事情并没有那么简单,因为对象可能具有引用其他复杂对象的属性,而关系模型要求值是原子的(即第一范式)(见图 38.1)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  If an object has only attributes of primitive data types, the mapping is straightforward. But as we will see, matters are not that simple, since objects may have attributes that refer to other complex objects, while the relational model requires that values be atomic (that is, First Normal Form) (see Figure 38.1).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  图 38.1.映射对象和表。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    38.7. UML 数据建模配置文件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    38.7. UML Data Modeling Profile

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    在 RDB 主题上,UML 已成为数据模型的流行符号,这并不奇怪。请注意,官方的 UP 工件之一是 Data Model,它是 Design 学科的一部分。图 38.2 说明了 UML 中用于数据建模的一些表示法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While on the subject of RDBs, not surprisingly, the UML has become a popular notation for data models. Note that one of the official UP artifacts is the Data Model, which is part of the Design discipline. Figure 38.2 illustrates some notation in the UML for data modeling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    图 38.2.UML 数据建模配置文件示例。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这些刻板印象不是核心 UML 的一部分,它们是一个扩展。概括地说,UML 具有 UML 配置文件的概念:一组连贯的 UML 构造型、标记值和用于特定目的的约束。图 38.2 说明了建议的 Data Modeling Profile 的一部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    These stereotypes are not part of the core UMLthey are an extension. To generalize, the UML has the concept of a UML profile: a coherent set of UML stereotypes, tagged values, and constraints for a particular purpose. Figure 38.2 illustrates part of a proposed Data Modeling Profile.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      38.8. 模式:对象标识符

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      38.8. Pattern: Object Identifier

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      最好有一种一致的方法将对象与记录相关联,并且能够确保记录的重复具体化不会导致重复的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It is desirable to have a consistent way to relate objects to records, and to be able to ensure that repeated materialization of a record does not result in duplicate objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对象标识符模式 [BW96] 建议为每个记录和对象(或对象的代理)分配一个对象标识符 (OID)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Object Identifier pattern [BW96] proposes assigning an object identifier (OID) to each record and object (or proxy of an object).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OID 通常是字母数字值;每个对象对于特定对象都是唯一的。有多种方法可以为 OID 生成唯一 ID,从单个数据库的唯一 ID 到全局唯一 ID:数据库序列生成器、高-低键生成策略 [Ambler00] 等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An OID is usually an alphanumeric value; each is unique to a specific object. There are various approaches to generating unique IDs for OIDs, ranging from unique to one database, to globally unique: database sequence generators, the High-Low key generation strategy [Ambler00], and others.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 object land 中,OID 由封装实际值及其表示的 OID 接口或类表示。在 RDB 中,它通常存储为固定长度的字符值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Within object land, an OID is represented by an OID interface or class that encapsulates the actual value and its representation. In an RDB, it is usually stored as a fixed length character value.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      每个表都将有一个 OID 作为主键,并且每个对象也将(直接或间接)具有一个 OID。如果每个对象都与 OID 相关联,并且每个 table 都有一个 OID 主键,则每个对象都可以唯一地 Map 到某个 table 中的某一行(请参见图 38.3)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Every table will have an OID as primary key, and each object will (directly or indirectly) also have an OID. If every object is associated with an OID, and every table has an OID primary key, every object can be uniquely mapped to some row in some table (see Figure 38.3).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.3.对象标识符链接对象和记录。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这是设计的简化视图。实际上,OID 实际上可能不会放置在持久对象中尽管这是可能的。相反,它可以放置在包装持久对象的 Proxy 对象中。设计受到语言选择的影响。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is a simplified view of the design. In reality, the OID may not actually be placed in the persistent objectalthough that is possible. Instead, it may be placed in a Proxy object wrapping the persistent object. The design is influenced by the choice of language.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OID 还提供一致的密钥类型,以便在持久性服务的接口中使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An OID also provides a consistent key type to use in the interface to the persistence service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.9. 使用 Facade 访问 Persistence 服务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.9. Accessing a Persistence Service with a Facade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        此子系统设计的第一步是为其服务定义 Facade;回想一下,Facade 是为子系统提供统一接口的常见模式。首先,需要一个操作来检索给定 OID 的对象。但除了 OID 之外,子系统还需要知道要具体化的对象类型;因此,还将提供 class type。图 38.4 说明了 Facade 的一些操作及其与 NextGen 服务适配器之一的协作使用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Step one in the design of this subsystem is to define a facade for its services; recall that Facade is a common pattern to provide a unified interface to a subsystem. To begin, an operation is needed to retrieve an object given an OID. But in addition to an OID, the subsystem needs to know what type of object to materialize; therefore, the class type will also be provided. Figure 38.4 illustrates some operations of the facade and its use in collaboration with one of the NextGen service adapters.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 38.4.PersistenceFacade 的标志。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.10. 映射对象:Database Mapper 或 Database Broker 模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.10. Mapping Objects: Database Mapper or Database Broker Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          与所有 Facade 一样,PersistenceFacade本身不执行工作,而是将请求委托给子系统对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The PersistenceFacadeas true of all facadesdoes not do the work itself, but delegates requests to subsystem objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          谁应该负责持久化存储中的对象(例如,ProductDescription)的具体化和非具体化?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who should be responsible for materialization and dematerialization of objects (for example, a ProductDescription) from a persistent store?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Information Expert 模式表明持久对象类本身 (ProductDescription) 是一个候选对象,因为它具有职责所需的一些数据(要保存的数据)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Information Expert pattern suggests that the persistent object class itself (ProductDescription) is a candidate, because it has some of the data (the data to be saved) required by the responsibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果持久性对象类定义了将自身保存在数据库中的代码,则称为直接映射设计。如果数据库相关代码是由后处理编译器自动生成并注入到类中的,那么直接映射是可行的,并且开发人员永远不必看到或维护这些复杂的数据库代码,使他或她的类变得杂乱无章。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If a persistent object class defines the code to save itself in a database, it is called a direct mapping design. Direct mapping is workable if the database related code is automatically generated and injected into the class by a post-processing compiler, and the developer never has to see or maintain this complex database code cluttering his or her class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          但是,如果手动添加和维护直接映射,则它存在许多缺陷,并且在编程和维护方面往往不能很好地扩展。问题包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          But if direct mapping is manually added and maintained, it has a number of defects and does not tend to scale well in terms of programming and maintenance. Problems include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 持久化对象类与持久化存储知识的强耦合违反了低耦合性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Strong coupling of the persistent object class to persistent storage knowledgeviolation of Low Coupling.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 在一个新的、与对象之前负责的无关的领域中承担复杂的责任违反了 High Cohesion 并保持关注点分离。技术服务问题与应用程序逻辑问题混合在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Complex responsibilities in a new and unrelated area to what the object was previously responsible forviolation of High Cohesion and maintaining a separation of concerns. Technical service concerns are mixing with application logic concerns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          我们将探索一种经典的间接映射方法,该方法使用其他对象来执行持久对象的映射。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We will explore a classic indirect mapping approach, that uses other objects to do the mapping for persistent objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这种方法的一部分是使用 Database Broker 模式 [BW95]。它建议创建一个负责具体化、非物质化和对象缓存的类。这在 [Fowler01] 中也被称为 Database Mapper 模式,这个名字比 Database Broker 更好,因为它描述了它的责任,而分布式系统 [BMRSS96] 设计中的术语 “broker” 有着悠久而不同的含义。[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Part of this approach is to use the Database Broker pattern [BW95]. It proposes making a class that is responsible for materialization, dematerialization, and object caching. This has also been called the Database Mapper pattern in [Fowler01], which is a better name than Database Broker, as it describes its responsibility, and the term "broker" in distributed systems [BMRSS96] design has a long-standing and different meaning.[1]

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] 在分布式系统中,代理是将任务委派给后端服务器进程的前端服务器进程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          [1] In distributed systems, a broker is a front-end server process that delegates tasks to back-end server processes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          为每个持久对象类定义了不同的 Mapper 类。图 38.5 说明了每个持久对象可能都有自己的 Mapper 类,并且对于不同的存储机制,可能有不同类型的 Mapper。一段代码:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A different mapper class is defined for each persistent object class. Figure 38.5 illustrates that each persistent object may have its own mapper class, and that there may be different kinds of mappers for different storage mechanisms. A snippet of code:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class PersistenceFacade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public Object get( OID oid, Class persistenceClass )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // an IMapper is keyed by the Class of the persistent object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             IMapper mapper = (IMapper) mappers.get( persistenceClass );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // delegate
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             return mapper.get( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class PersistenceFacade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          public Object get( OID oid, Class persistenceClass )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // an IMapper is keyed by the Class of the persistent object
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             IMapper mapper = (IMapper) mappers.get( persistenceClass );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // delegate
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             return mapper.get( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 38.5.数据库映射器。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          尽管此图指示两个 ProductDescription 映射器,但在正在运行的持久性服务中只有一个映射器处于活动状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Although this diagram indicates two ProductDescription mappers, only one will be active within a running persistence service.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          基于元数据的映射器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Metadata-Based Mappers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          更灵活但涉及更多的是基于元数据 (有关数据的数据) 的映射器设计。与为不同的持久类型手动创建单个映射器类相比,基于元数据的映射器根据读取描述映射的元数据动态生成从对象架构到另一个架构(例如关系架构)的映射,例如“TableX 映射到类 Y;Z 列映射到对象属性 P“(它变得更加复杂)。这种方法对于具有反射编程功能的语言(如 Java、C# 或 Smalltalk)是可行的,而对于没有反射编程功能的语言(如 C++)来说则很笨拙。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          More flexible, but more involved, is a mapper design based on metadata (data about data). In contrast to hand-crafting individual mapper classes for different persistent types, metadata-based mappers dynamically generate the mapping from an object schema to another schema (such as relational) based on reading in metadata that describes the mapping, such as "TableX maps to Class Y; column Z maps to object property P" (it gets much more complex). This approach is feasible for languages with reflective programming capabilities, such as Java, C#, or Smalltalk, and awkward for those that don't, such as C++.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          使用基于元数据的映射器,我们可以在外部存储中更改模式映射,并且它将在正在运行的系统中实现,而无需更改源代码 Protected Variations 关于模式变体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          With metadata-based mappers, we can change the schema mapping in an external store and it will be realized in the running system, without changing source codeProtected Variations with respect to schema variations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          尽管如此,这里介绍的框架的一个有用特性是可以使用手动编码或元数据映射器,而不会影响 clientencapsulation 的实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Nevertheless, a useful quality of the framework presented here is that hand-coded or metadata mappers can be used without affecting clientsencapsulation of the implementation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.11. 使用模板方法模式进行框架设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.11. Framework Design with the Template Method Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            下一节将介绍 Database Mapper 的一些基本设计功能,这些功能是 PFW 的核心部分。这些设计功能基于模板方法 GoF 设计模式 [GHJV95]。[2] 这种模式是框架设计的核心,[3] 大多数 OO 程序员即使不是名字,也在实践中很熟悉。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The next section describes some of the essential design features of the Database Mappers, which are a central part of the PFW. These design features are based on the Template Method GoF design pattern [GHJV95].[2] This pattern is at the heart of framework design,[3] and is familiar to most OO programmers by practice if not by name.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [2] 此模式与 C++ 模板无关。它描述了算法的模板

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [2] This pattern is unrelated to C++ templates. It describes the template of an algorithm.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] 更具体地说,是白盒框架。这些通常是面向类层次结构和子类化的框架,需要用户了解他们的设计和结构;因此,Whitebox 会问世。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [3] More specifically, of whitebox frameworks. These are usually class hierarchy and subclassing-oriented frameworks that require the user to know something about their design and structure; hence, whitebox.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            这个想法是在超类中定义一个方法(Template Method),该方法定义算法的框架,以及其可变和不可变的部分。Template Method 调用其他方法,其中一些方法是可能在子类中重写的方法。因此,子类可以覆盖不同的方法,以便在可变点添加自己独特的行为(参见图 38.6)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The idea is to define a method (the Template Method) in a superclass that defines the skeleton of an algorithm, with its varying and unvarying parts. The Template Method invokes other methods, some of which are methods that may be overridden in a subclass. Thus, subclasses can override the varying methods in order to add their own unique behavior at points of variability (see Figure 38.6).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 38.6.GUI 框架中的模板方法模式。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.12. 使用 Template Method 模式实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.12. Materialization with the Template Method Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如果我们要对两个或三个 mapper 类进行编程,代码中的一些通用性就会变得很明显。用于具体化对象的基本重复算法结构为:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              If we were to program two or three mapper classes, some commonality in the code would become apparent. The basic repeating algorithm structure for materializing an object is:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              if (object in cache)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 return it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              else
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 create the object from its representation in storage
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 save object in cache
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 return it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              if (object in cache)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 return it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              else
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 create the object from its representation in storage
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 save object in cache
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 return it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              变化点是如何从存储创建对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The point of variation is how the object is created from storage.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              我们将创建 get 方法作为定义模板的抽象超类 AbstractPersistenceMapper 中的模板方法,并在子类中为不同的部分使用 hook 方法。图 38.7 显示了基本设计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We will create the get method to be the template method in an abstract superclass AbstractPersistenceMapper that defines the template, and use a hook method in subclasses for the varying part. Figure 38.7 shows the essential design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.7.映射器对象的模板方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              如本例所示,模板方法是 public 的,而 hook 方法是受保护的。AbstractPersistenceMapperIMapper 是 PFW 的一部分。现在,应用程序程序员可以通过添加子类并覆盖或实现 getObjectFromStorage 钩子方法来插入此框架。图 38.8 显示了一个示例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As shown in this example, it is common for the template method to be public, and the hook method to be protected. AbstractPersistenceMapper and IMapper are part of the PFW. Now, an application programmer can plug into this framework by adding a subclass, and overriding or implementing the getObjectFromStorage hook method. Figure 38.8 shows an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.8.重写 hook 方法。[4]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [4] 以 Java 为例,执行 SQL 查询返回的 dbRec 将是 JDBC ResultSet

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [4] In Java as an example, the dbRec that is returned from executing a SQL query will be a JDBC ResultSet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              假设在图 38.8 的钩子方法实现中,执行 SQL SELECT 的算法的开头部分对于所有对象都是相同的,只是数据库表名不同。[5]如果这个假设成立,那么可以再次应用模板方法模式来分解算法的不同和不变部分。在图 38.9 中,棘手的部分是 AbstractRDBMapper.getObjectFromStorage 是关于 AbstractPersistenceMapper.get 的钩子方法,但是对于新的钩子方法 getObjectFromRecord 来说是一个模板方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Assume in the hook method implementation of Figure 38.8 that the beginning part of the algorithmdoing a SQL SELECTis the same for all objects, only the database table name varies.[5] If that assumption held, then once again, the Template Method pattern could be applied to factor out the varying and unvarying parts of the algorithm. In Figure 38.9, the tricky part is that AbstractRDBMapper.getObjectFromStorage is a hook method with respect to AbstractPersistenceMapper.get, but a template method with respect to the new hook method getObjectFromRecord.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [5]在许多情况下,情况并不那么简单。对象可以从两个或多个表或多个数据库的数据派生,在这种情况下,模板方法设计的第一个版本提供了更大的灵活性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [5] In many cases, the situation is not so simple. An object may be derived from data from two or more tables or from multiple databases, in which case, the first version of the Template Method design offers more flexibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.9.再次使用 Template Method 收紧代码。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML图 38.9 中,观察如何在 UML 中声明构造函数。构造型是可选的,如果使用构造函数名称等于类名称的命名约定,则可能没有必要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML In Figure 38.9 observe how constructors can be declared in the UML. The stereotype is optional, and if the naming convention of constructor name equal to class name is used, probably unnecessary.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              现在,IMapper、AbstractPersistenceMapperAbstractRDBMapper 是框架的一部分。应用程序程序员只需要添加他或她的子类,例如 ProductDescriptionRDBMapper,并确保它是用表名创建的(通过构造函数链接传递给 AbstractRDBMapper)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Now, IMapper, AbstractPersistenceMapper, and AbstractRDBMapper are part of the framework. The application programmer needs only to add his or her subclass, such as ProductDescriptionRDBMapper, and ensure it is created with the table name (to pass via constructor chaining up to the AbstractRDBMapper).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Database Mapper 类层次结构是框架的重要组成部分;应用程序程序员可以添加新的子类,以便为新的持久存储机制或现有存储机制中的新特定表或文件对其进行自定义。图 38.10 显示了一些 package 和 class 结构。请注意,特定于 NextGen 的类不属于通用技术服务 Persistence 包。我认为这张图与图 38.9 相结合,说明了像 UML 这样的可视化语言在描述软件部分方面的价值;这简洁地传达了很多信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Database Mapper class hierarchy is an essential part of the framework; new subclasses may be added by the application programmer to customize it for new kinds of persistent storage mechanisms or for new particular tables or files within an existing storage mechanism. Figure 38.10 shows some of the package and class structure. Notice that the NextGen-specific classes do not belong in the general technical services Persistence package. I think this diagram, combined with Figure 38.9, illustrates the value of a visual language like the UML to describe parts of software; this succinctly conveys much information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.10.持久性框架。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.10 中,请注意类 ProductDescriptionInMemoryTestDataMapper。此类可用于提供硬编码对象以进行测试,而无需访问任何外部持久存储。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In Figure 38.10 notice the class ProductDescriptionInMemoryTestDataMapper. Such classes can be used to serve up hard-coded objects for testing, without accessing any external persistent store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UP 和软件架构文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The UP and the Software Architecture Document

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              就 UP 和文档而言,回想一下,SAD 是未来开发人员的学习辅助工具,其中包含关键值得注意的想法的架构视图。在 NextGen 项目的 SAD 中包含图 38.9图 38.10 等图表,这非常符合 SAD 应包含的信息类型的精神。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In terms of the UP and documentation, recall that the SAD is a learning aid for future developers, which contains architectural views of key noteworthy ideas. Including diagrams such as Figure 38.9 and Figure 38.10 in the SAD for the NextGen project is very much in the spirit of the kind of information an SAD should contain.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 中的同步或保护方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Synchronized or Guarded Methods in the UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              AbstractPersistenceMapper.get 方法包含非线程安全的关键部分代码,同一对象可以在不同的线程上同时实现。作为技术服务子系统,持久化服务在设计时需要考虑到线程安全。事实上,整个子系统可以被分发到另一台计算机上的单独进程,PersistenceFacade 被转换为远程服务器对象,并且许多线程同时在子系统中运行,为多个客户端提供服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The AbstractPersistenceMapper.get method contains critical section code that is not thread safethe same object could be materializing concurrently on different threads. As a technical service subsystem, the persistence service needs to be designed with thread safety in mind. Indeed, the entire subsystem may be distributed to a separate process on another computer, with the PersistenceFacade transformed into a remote server object, and with many threads simultaneously running in the subsystem, serving multiple clients.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              因此,该方法应具有线程并发控制如果使用 Java,请添加 synchronized 关键字。图 38.11 说明了类图中的同步方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The method should therefore have thread concurrency controlif using Java, add the synchronized keyword. Figure 38.11 illustrates a synchronized method in a class diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.11.UML 中的受保护方法。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.13. 使用 MapperFactory 配置 Mapper

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.13. Configuring Mappers with a MapperFactory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                与案例研究中前面的工厂示例类似,可以使用工厂对象 MapperFactory 实现具有一组 IMapper 对象的 PersistenceFacade 的配置。但是,作为一个小小的改变,最好不要使用不同的操作来命名每个映射器。例如,这是不可取的:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Similar to previous examples of factories in the case study, the configuration of the PersistenceFacade with a set of IMapper objects can be achieved with a factory object, MapperFactory. However, as a slight twist, it is desirable to not name each mapper with a different operation. For example, this is not desirable:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class MapperFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public IMapper getProductDescriptionMapper() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public IMapper getSaleMapper() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class MapperFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public IMapper getProductDescriptionMapper() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public IMapper getSaleMapper() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这不支持 Protected Variations 关于不断增长的 mapper,并且它会增长。因此,以下选项是首选:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This does not support Protected Variations with respect to a growing list of mappersand it will grow. Consequently, the following is preferred:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class MapperFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public Map getAllMappers() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class MapperFactory
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                public Map getAllMappers() {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                其中 java.util.Map(可能使用 HashMap 实现)键是 Class 对象(持久类型),IMappers 是值。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                where the java.util.Map (probably implemented with a HashMap) keys are the Class objects (the persistent types), and the IMappers are the values.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                然后,外观可以初始化其 IMappers 集合,如下所示:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Then, the facade can initialize its collection of IMappers as follows:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class PersistenceFacade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                private java.util.Map mappers =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   MapperFactory.getInstance().getAllMappers();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                class PersistenceFacade
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                private java.util.Map mappers =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   MapperFactory.getInstance().getAllMappers();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                工厂可以使用数据驱动设计分配一组 IMappers。也就是说,工厂可以读取系统属性以发现要实例化的 IMapper 类。如果使用具有反射编程功能的语言,例如 Java,则实例化可以基于将类名作为字符串读取,并使用类似 Class.newInstance 操作的内容进行实例化。因此,可以在不更改源代码的情况下重新配置映射器集。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The factory can assign a set of IMappers using a data-driven design. That is, the factory can read system properties to discover which IMapper classes to instantiate. If a language with reflective programming capabilities is used, such as Java, then the instantiation can be based on reading in the class names as strings, and using something like a Class.newInstance operation for instantiation. Thus, the mapper set can be reconfigured without changing the source code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  38.14. 模式:缓存管理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  38.14. Pattern: Cache Management

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  最好在本地缓存中维护具体化对象,以提高性能(具体化相对较慢)并支持事务管理操作,例如提交。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  It is desirable to maintain materialized objects in a local cache to improve performance (materialization is relatively slow) and support transaction management operations such as a commit.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  缓存管理模式 [BW96] 建议让数据库映射器负责维护其缓存。如果每个持久性对象类使用不同的映射器,则每个映射器都可以维护自己的缓存。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Cache Management pattern [BW96] proposes making the Database Mappers responsible for maintaining its cache. If a different mapper is used for each class of persistent object, each mapper can maintain its own cache.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当对象具体化时,它们被放置在缓存中,其 OID 作为键。向 mapper 请求对象的后续请求将导致 mapper 首先搜索缓存,从而避免不必要的实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  When objects are materialized, they are placed in the cache, with their OID as the key. Subsequent requests to the mapper for an object will cause the mapper to first search the cache, thus avoiding unnecessary materialization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    38.15. 在一个类中合并和隐藏 SQL 语句

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    38.15. Consolidating and Hiding SQL Statements in One Class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    将 SQL 语句硬编码到不同的 RDB 映射器类中并不是一件可怕的罪,但可以改进。假设:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Hard-coding SQL statements into different RDB mapper classes is not a terrible sin, but it can be improved upon. Suppose instead:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 有一个 Pure Fabrication 类(它是一个单例)RDBOperations,其中所有 SQL 操作(SELECT、INSERT 等)都被整合在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • There is a single Pure Fabrication class (and it's a singleton) RDBOperations where all SQL operations (SELECT, INSERT, ...) are consolidated.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • RDB 映射器类与它协作以获取 DB 记录或记录集(例如 ResultSet)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • The RDB mapper classes collaborate with it to obtain a DB record or record set (for example, ResultSet).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 它的界面看起来像这样:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class RDBOperations
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public ResultSet getProductDescriptionData( OID oid ) {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public ResultSet getSaleData( OID oid ) {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Its interface looks something like this:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      class RDBOperations
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public ResultSet getProductDescriptionData( OID oid ) {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public ResultSet getSaleData( OID oid ) {...}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    因此,例如,映射器具有如下代码:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    So that, for example, a mapper has code like this:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ps.setOID( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    return ps;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ps.setOID( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    return ps;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    这种纯制造可带来以下好处:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The following benefits accrue from this Pure Fabrication:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 易于专家维护和性能调整。SQL 优化需要 SQL 爱好者,而不是对象程序员。由于所有 SQL 都嵌入到这个类中,因此 SQL 专家很容易找到并处理它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Ease of maintenance and performance tuning by an expert. SQL optimization requires a SQL aficionado, rather than an object programmer. With all the SQL embedded in this one class, it is easy for the SQL expert to find and work on it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • 访问方法和详细信息的封装。例如,硬编码的 SQL 可以替换为对 RDB 中存储过程的调用,以便获取数据。或者,可以插入一种更复杂的基于元数据的方法来生成 SQL,其中 SQL 是从从外部源读取的元数据架构描述动态生成的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Encapsulation of the access method and details. For example, hard-coded SQL could be replaced by a call to a stored procedure in the RDB in order to obtain the data. Or a more sophisticated metadata-based approach to generating the SQL could be inserted, in which SQL is dynamically generated from a metadata schema description read from an external source.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    作为架构师,此设计决策的有趣之处在于它受开发人员技能的影响。在高凝聚力和专家的便利性之间进行了权衡。并非所有设计决策都是由 “纯粹” 软件工程关注点(如耦合和内聚)驱动的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As an architect, the interesting aspect of this design decision is that it is influenced by developer skills. A trade-off between high cohesion and convenience for a specialist was made. Not all design decisions are motivated by "pure" software engineering concerns such as coupling and cohesion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      38.16. 事务状态和状态模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      38.16. Transactional States and the State Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      事务性支持问题可能会变得复杂,但为了简单起见,目前要专注于 GoF 状态模式,请假定以下内容:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Transactional support issues can get complex, but to keep things simple for the presentto focus on the GoF State patternassume the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 可以插入、删除或修改持久性对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Persistent objects can be inserted, deleted, or modified.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 对持久性对象进行操作(例如,修改它)不会导致立即更新数据库;相反,必须执行显式提交操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Operating on a persistent object (for example, modifying it) does not cause an immediate database update; rather, an explicit commit operation must be performed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      此外,对操作的响应取决于对象的事务状态。例如,响应可能如图 38.12 的状态图所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In addition, the response to an operation depends on the transactional state of the object. As an example, responses may be as shown in the statechart of Figure 38.12.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.12.PersistentObject 的状态图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,“old dirty” 对象是从数据库中检索然后修改的对象。在提交操作中,它应该更新到数据库,而不是处于 “old clean” 状态的数据库,后者应该什么都不做(因为它没有改变)。在面向对象的 PFW 中,执行删除或保存操作时,它不会立即导致数据库删除或保存;相反,持久化对象会转换到适当的状态,等待提交或回滚来真正执行某些操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, an "old dirty" object is one retrieved from the database and then modified. On a commit operation, it should be updated to the databasein contrast to one in the "old clean" state, which should do nothing (because it hasn't changed). Within the object-oriented PFW, when a delete or save operation is performed, it does not immediately cause a database delete or save; rather, the persistent object transitions to the appropriate state, awaiting a commit or rollback to really do something.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      作为 UML 注释,这是一个很好的示例,说明状态图有助于简洁地传达否则难以表达的信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As a UML comment, this is a good example of where a statechart is helpful in succinctly communicating information that is otherwise awkward to express.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在这个设计中,假设我们将使所有持久化对象类都扩展一个 PersistentObject 类,[6] 该类为持久化提供通用的技术服务。[7] 例如,参见图 38.13

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In this design, assume that we will make all persistent object classes extend a PersistentObject class,[6] that provides common technical services for persistence.[7] For example, see Figure 38.13.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [6] [Ambler00b] 是关于 PersistentObject 类和持久化层的一个很好的参考,尽管这个想法更古老。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [6] [Ambler00b] is a good reference on a PersistentObject class and persistence layers, although the idea is older.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [7] 扩展 PersistentObject 类的一些问题将在后面讨论。每当域对象类扩展技术服务类时,都应该暂停进行反射,因为它混合了体系结构关注点(持久性和应用程序逻辑)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [7] Some issues with extending a PersistentObject class are discussed later. Whenever a domain object class extends a technical services class, it should be pause for reflection, as it mixes architectural concerns (persistence and application logic).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.13.持久对象。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      现在,这是将通过 State patternnotice 解决的问题,即 commitrollback 方法需要基于事务性状态代码的类似 case logic结构。commitrollback 在它们的情况下执行不同的操作,但它们具有相似的逻辑结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Nowand this is the issue that will be resolved with the State patternnotice that commit and rollback methods require similar structures of case logic, based on a transactional state code. commit and rollback perform different actions in their cases, but they have similar logic structures.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public void commit()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      switch ( state )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_DIRTY:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_CLEAN:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public void commit()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      switch ( state )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_DIRTY:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_CLEAN:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public void rollback()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      switch ( state )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_DIRTY:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_CLEAN:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      public void rollback()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      switch ( state )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_DIRTY:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      case OLD_CLEAN:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          //...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         break;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这种 repeating case logic 结构的替代方案是 GoF State 模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An alternative to this repeating case logic structure is the GoF State pattern.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      State

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      上下文/问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Context/Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对象的行为取决于其状态,并且其方法包含反映条件状态相关操作的 case 逻辑。有没有条件逻辑的替代方案?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An object's behavior is dependent on its state, and its methods contain case logic reflecting conditional state-dependent actions. Is there an alternative to conditional logic?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      为每个状态创建状态类,实现一个通用接口。将依赖于状态的操作从上下文对象委托给其当前状态对象。确保上下文对象始终指向反映其当前状态的状态对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Create state classes for each state, implementing a common interface. Delegate state-dependent operations from the context object to its current state object. Ensure the context object always points to a state object reflecting its current state.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.14 说明了它在 persistence 子系统中的应用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Figure 38.14 illustrates its application in the persistence subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.14.应用 State 模式。[10]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [10] 由于图中的空间限制,省略了 Deleted 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [10] The Deleted class is omitted due to space constraints in the diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      PersistentObject 中依赖于状态的方法将其执行委托给关联的状态对象。如果上下文对象引用 OldDirtyState,则 1) 提交方法将导致数据库更新,并且 2) 上下文对象将被重新分配以引用 OldCleanState。另一方面,如果上下文对象引用 OldCleanState,则继承的 do-nothing 提交方法将执行并且不执行任何操作(正如预期的那样,因为该对象是干净的)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      State-dependent methods in PersistentObject delegate their execution to an associated state object. If the context object is referencing the OldDirtyState, then 1) the commit method will cause a database update, and 2) the context object will be reassigned to reference the OldCleanState. On the other hand, if the context object is referencing the OldCleanState, the inherited do-nothing commit method executes and does nothing (as to be expected, since the object is clean).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      图 38.14 中观察到状态类及其行为对应于图 38.12 中的状态图。状态模式是在软件中实现状态转换模型的一种机制。[8]它使对象响应事件转换到不同的状态。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Observe in Figure 38.14 that the state classes and their behavior correspond to the state chart of Figure 38.12. The State pattern is one mechanism to implement a state transition model in software.[8] It causes an object to transition to different states in response to events.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [8]还有其他方法,包括硬编码的条件逻辑、状态机解释器和由状态表驱动的代码生成器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [8] There are others, including hard-coded conditional logic, state machine interpreters, and code generators driven by state tables.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      作为性能注释,这些 state 对象具有讽刺意味的是 stateless (没有 attributes)。因此,不需要有多个 classeach 是单例的实例。例如,数千个持久对象可以引用同一个 OldDirtyState 实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As a performance comment, these state objects areironicallystateless (no attributes). Thus, there does not need to be multiple instances of a classeach is a singleton. Thousands of persistent objects can reference the same OldDirtyState instance, for example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.17. 使用命令模式设计事务

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        38.17. Designing a Transaction with the Command Pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        最后一部分对交易进行了简化。本节扩展了讨论,但并未涵盖所有事务设计问题。非正式地,事务是一个工作单元一组任务,其任务必须全部成功完成,或者必须完成任何任务。也就是说,它的完成是原子的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The last section took a simplified view of transactions. This section extends the discussion, but does not cover all transaction design issues. Informally, a transaction is a unit of worka set of taskswhose tasks must all complete successfully, or none must be completed. That is, its completion is atomic.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        就持久化服务而言,事务的任务包括插入、更新和删除对象。例如,一个事务可以包含两个 insert、one update 和 3 个删除。为了表示这一点,添加了一个 Transaction 类 [Ambler00b]。[9] 正如 [Fowler01] 中指出的,事务中数据库任务的顺序会影响其成功(和性能)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In terms of the persistence service, the tasks of a transaction include inserting, updating, and deleting objects. One transaction could contain two inserts, one update, and three deletes, for example. To represent this, a Transaction class is added [Ambler00b].[9] As pointed out in [Fowler01], the order of database tasks within a transaction can influence its success (and performance).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [9] 这在 [Fowler02] 中称为 UnitOfWork。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [9] This is called a UnitOfWork in [Fowler02].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        例如:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1. 假设数据库具有引用完整性约束,因此,当 TableA 中的记录包含 TableB 中记录的外键时,数据库要求 TableB 中的记录已经存在。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Suppose the database has a referential integrity constraint such that when a record is updated in TableA that contains a foreign key to a record in TableB, the database requires that the record in TableB already exists.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        3. 假设事务包含一个用于添加 TableB 记录的 INSERT 任务和一个用于更新 TableA 记录的 UPDATE 任务。如果 UPDATE 在 INSERT 之前执行,则会引发引用完整性错误。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        4. Suppose a transaction contains an INSERT task to add the TableB record, and an UPDATE task to update the TableA record. If the UPDATE executes before the INSERT, a referential integrity error is raised.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对数据库任务进行排序会有所帮助。某些排序问题是特定于架构的,但一般策略是首先执行插入,然后更新,然后删除。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Ordering the database tasks can help. Some ordering issues are schema-specific, but a general strategy is to first do inserts, then updates, and then deletes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        请注意,应用程序将任务添加到事务中的顺序可能无法反映其最佳执行顺序。任务需要在执行之前进行排序。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Mind that the order in which tasks are added to a transaction by an application may not reflect their best execution order. The tasks need to be sorted just before their execution.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这导致了另一个 GoF 模式:Command。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This leads to another GoF pattern: Command.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        命令

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Command

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        上下文/问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Context/Problem

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如何处理需要排序(优先级)、排队、延迟、日志记录或撤消等功能的请求或任务?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        How to handle requests or tasks that need functions such as sorting (prioritizing), queueing, delaying, logging, or undoing?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        使每个任务成为实现公共接口的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Make each task a class that implements a common interface.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        这是一个具有许多有用应用程序的简单模式;操作成为对象,因此可以进行排序、记录、排队等。例如,在 PFW 中,图 38.15 显示了数据库操作的 Command (或 task) 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This is a simple pattern with many useful applications; actions become objects, and thus can be sorted, logged, queued, and so forth. For example, in the PFW, Figure 38.15 shows Command (or task) classes for the database operations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 38.15.用于数据库操作的命令。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        完成事务解决方案还有很多工作要做,但本节的关键思想是将事务中的每个任务或操作表示为具有多态 execute 方法的对象;通过将请求视为对象本身,这打开了一个灵活的世界。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There is much more to completing a transaction solution, but the key idea of this section is to represent each task or action in the transaction as an object with a polymorphic execute method; this opens up a world of flexibility by treating the request as an object itself.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Command 的典型示例是 GUI 操作,例如剪切和粘贴。例如,CutCommand 的 execute 方法执行剪切,其 undo 方法撤消剪切。CutCommand 还将保留执行撤消所需的数据。所有 GUI 命令都可以保存在历史堆栈中,以便依次弹出它们,并撤消每个命令。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The quintessential example of Command is for GUI actions, such as cut and paste. For example, the CutCommand's execute method does a cut, and its undo method reverses the cut. The CutCommand will also retain the data necessary to perform the undo. All the GUI commands can be kept in a history stack, so that they can be popped in turn, and each undone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Command 的另一个常见用途是服务器端请求处理。当服务器对象收到 (远程) 消息时,它会为该请求创建一个 Command 对象,并将其传递给 CommandProcesser [BMRSS96],后者可以对命令进行排队、记录、确定优先级和执行命令。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Another common use of Command is for server-side request handling. When a server object receives a (remote) message, it creates a Command object for that request, and hands it off to a CommandProcesser [BMRSS96], which can queue, log, prioritize, and execute the commands.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.18. 使用虚拟代理的惰性物化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          38.18. Lazy Materialization with a Virtual Proxy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          有时希望将对象的实现推迟到绝对需要时,通常是出于性能原因。例如,假设 ProductDescription 对象引用 Manufacturer 对象,但很少需要从数据库中具体化该对象。只有极少数情况会导致请求制造商信息,例如需要公司名称和地址的制造商返利情况。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It is sometimes desirable to defer the materialization of an object until it is absolutely required, usually for performance reasons. For example, suppose that ProductDescription objects reference a Manufacturer object, but only very rarely does it need to be materialized from the database. Only rare scenarios cause a request for manufacturer information, such as manufacturer rebate scenarios in which the company name and address are required.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “子”对象的延迟具体化称为延迟具体化。惰性物化可以使用 Virtual Proxy GoF 模式实现,这是 Proxy 的众多变体之一。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The deferred materialization of "children" objects is known as lazy materialization. Lazy materialization can be implemented using the Virtual Proxy GoF patternone of many variations of Proxy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          虚拟代理是另一个对象 (真实主题) 的代理,它在首次引用时实现真实主题;因此,它实现了 Lazy Materialization。它是一个轻量级的物体,代表一个 “真实 ”的物体,它可能会也可能不会被物化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A Virtual Proxy is a proxy for another object (the real subject) that materializes the real subject when it is first referenced; therefore, it implements lazy materialization. It is a lightweight object that stands for a "real" object that may or may not be materialized.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 38.16 显示了带有 ProductDescriptionManufacturer 的 Virtual Proxy 模式的具体示例。此设计基于以下假设:代理知道其真实主题的 OID,当需要具体化时,OID 用于帮助识别和检索真实主题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A concrete example of the Virtual Proxy pattern with ProductDescription and Manufacturer is shown in Figure 38.16. This design is based on the assumption that proxies know the OID of their real subject, and when materialization is required, the OID is used to help identify and retrieve the real subject.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 38.16.制造商虚拟代理。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,ProductDescription 具有对 IManufacturer 实例的 visibility 属性。此产品的制造商描述可能尚未在内存中具体化。当 ProductDescriptionManufacturerProxy 发送 getAddress 消息(就像它是具体化的 manufacturer 对象一样)时,代理会具体化真正的 Manufacturer,并使用 Manufacturer 的 OID 来检索和具体化它。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that the ProductDescription has attribute visibility to an IManufacturer instance. The Manufacturer for this ProductDescription may not yet be materialized in memory. When the ProductDescription sends a getAddress message to the ManufacturerProxy (as though it were the materialized manufacturer object), the proxy materializes the real Manufacturer, using the OID of the Manufacturer to retrieve and materialize it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          谁创建虚拟代理?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who Creates the Virtual Proxy?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 38.16 中观察到 ManufacturerProxyPersistenceFacade 协作以实现其真实主题。但是谁创建了 ManufacturerProxy?答案:ProductDescription 的数据库映射器类。映射器类负责决定在具体化对象时,它的哪些“子”对象也应该预先具体化,哪些对象应该使用代理延迟具体化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Observe in Figure 38.16 that the ManufacturerProxy collaborates with the PersistenceFacade in order to materialize its real subject. But who creates the ManufacturerProxy? Answer: The database mapper class for ProductDescription. The mapper class is responsible for deciding, when it materializes an object, which of its "child" objects should also be eagerly materialized, and which should be lazily materialized with a proxy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          考虑这些替代解决方案:一种使用急切具体化,另一种使用惰性具体化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Consider these alternative solutions: one uses eager materialization, the other lazy materialization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // EAGER MATERIALIZATION OF MANUFACTURER
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // here's the essence of it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          String manufacturerForeignKey = rs.getString( "MANU_OID" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          OID manuOID = new OID( manufacturerForeignKey );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setManufacturer( (IManufacturer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             PersistenceFacade.getInstance().get(manuOID,Manufacturer.class);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // EAGER MATERIALIZATION OF MANUFACTURER
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // here's the essence of it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          String manufacturerForeignKey = rs.getString( "MANU_OID" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          OID manuOID = new OID( manufacturerForeignKey );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setManufacturer( (IManufacturer)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             PersistenceFacade.getInstance().get(manuOID,Manufacturer.class);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          这是惰性物化解决方案:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Here is the lazy materialization solution:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // LAZY MATERIALIZATION OF MANUFACTURER
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // here's the essence of it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          String manufacturerForeignKey = rs.getString( "MANU_OID" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          OID manuOID = new OID( manufacturerForeignKey );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setManufacturer( new ManufacturerProxy( manuOID ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // LAZY MATERIALIZATION OF MANUFACTURER
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          class ProductDescriptionRDBMapper extends AbstractPersistenceMapper
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          protected Object getObjectFromStorage( OID oid )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ResultSet rs =
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             RDBOperations.getInstance().getProductDescriptionData( oid );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ProductDescription ps = new ProductDescription();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setPrice( rs.getDouble( "PRICE" ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             // here's the essence of it
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          String manufacturerForeignKey = rs.getString( "MANU_OID" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          OID manuOID = new OID( manufacturerForeignKey );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ps.setManufacturer( new ManufacturerProxy( manuOID ) );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          虚拟代理的实施

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Implementation of a Virtual Proxy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          虚拟代理的实现因语言而异。细节超出了本章的范围,但这里有一个概要:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The implementation of a Virtual Proxy varies by language. The details are outside the scope of this chapter, but here is a synopsis:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          语言

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Language

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          虚拟代理实施

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Virtual Proxy Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          C++

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          C++

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          定义模板化智能指针类。实际上不需要 IManufacturer 接口定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Define a templatized smart pointer class. No IManufacturer interface definition is actually needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          爪哇岛

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Java

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          实现了 ManufacturerProxy 类。定义了 IManufacturer 接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The ManufacturerProxy class is implemented. The IManufacturer interface is defined.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          但是,这些通常不会手动编码。相反,可以创建一个代码生成器来分析主题类(例如,Manufacturer)并生成 IManufacturerProxyManufacturer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          However, these are not normally manually coded. Rather, one creates a code generator that analyzes the subject classes (e.g., Manufacturer) and generates IManufacturer and ProxyManufacturer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          另一种 Java 替代方案是 Dynamic Proxy API。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Another Java alternative is the Dynamic Proxy API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          闲聊

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Smalltalk

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          定义一个 Virtual Morphing Proxy(或 Ghost Proxy),它使用 #doesNotUnderstand: 和 #become: 变形为真实主体。不需要 IManufacturer 定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Define a Virtual Morphing Proxy (or Ghost Proxy), which uses #doesNotUnderstand: and #become: to morph into the real subject. No IManufacturer definition is needed.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.19. 如何在表中表示关系

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            38.19. How to Represent Relationships in Tables

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            上一节中的代码依赖于 PRODUCT_SPEC 表中的 MANU_OID 外键链接到 MANUFACTURER 表中的记录。这突出了一个问题:对象关系在关系模型中如何表示?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The code in the prior section relies on a MANU_OID foreign key in the PRODUCT_SPEC table to link to a record in the MANUFACTURER table. This highlights the question: How are object relationships represented in the relational model?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            答案在将对象关系表示为表 模式 {BW96] 中给出,该模式建议如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The answer is given in the Representing Object Relationships as Tables pattern {BW96], which proposes the following:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 一对一关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 将 OID 外键放在一个或两个表中,这些表表示关系中的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 或者,创建一个关联表来记录关系中每个对象的 OID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • one-to-one associations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Place an OID foreign key in one or both tables representing the objects in relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Or, create an associative table that records the OIDs of each object in relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 一对多关联,例如集合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 创建一个关联表,用于记录关系中每个对象的 OID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • one-to-many associations, such as a collection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Create an associative table that records the OIDs of each object in relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • 多对多关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 创建一个关联表,用于记录关系中每个对象的 OID。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • many-to-many associations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Create an associative table that records the OIDs of each object in relationship.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.20. PersistentObject 超类和关注点分离

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              38.20. PersistentObject Superclass and Separation of Concerns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              为对象提供持久性的常见部分设计解决方案是创建一个抽象的技术服务超类 PersistentObject,所有持久性对象都继承自该超类(参见图 38.17)。此类通常定义持久性属性(例如唯一的 OID)和保存到数据库的方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A common partial design solution to providing persistence for objects is to create an abstract technical services superclass PersistentObject that all persistence objects inherit from (see Figure 38.17). Such a class usually defines attributes for persistence, such as a unique OID, and methods for saving to a database.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 38.17.PersistentObject 超类的问题。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这并没有错,但它的缺点是将类耦合到 PersistentObject 类域类最终扩展了一个技术服务类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is not wrong, but it suffers from the weakness of coupling the class to the PersistentObject classdomain classes end up extending a technical services class.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              此设计并未说明明确的关注点分离。相反,由于此扩展,技术服务关注点与域层业务逻辑关注点混合在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This design does not illustrate a clear separation of concerns. Rather, technical services concerns are mixed with domain layer business logic concerns by virtue of this extension.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              另一方面,“关注点分离”并不是必须不惜一切代价遵循的绝对美德。正如 Protected Variations 介绍中所讨论的,设计人员需要在真正可能代价高昂的不稳定点上选择他们的战斗。如果在某个特定的应用程序中,从 PersistentObject 扩展类可以带来一个简洁易用的解决方案,并且不会产生长期的设计或维护问题,为什么不呢?答案在于了解应用程序需求和设计的演变。它还受语言的影响:那些具有单一继承的(比如 Java)已经消耗了他们的单个珍贵的超类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              On the other hand, "separation of concerns" is not an absolute virtue that must be followed at all costs. As discussed in the Protected Variations introduction, designers need to pick their battles at the truly likely points of expensive instability. If in a particular application making the classes extend from PersistentObject leads to a neat and easy solution and does not create longer-term design or maintenance problems, why not? The answer lies in understanding the evolution of the requirements and design for the application. It is also influenced by the language: Those with single inheritance (such as Java) have had their single precious superclass consumed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.21. 未解决的问题

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                38.21. Unresolved Issues

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                这是对持久化框架和服务中的问题和设计解决方案的非常简短的介绍。许多重要问题都被掩盖了,包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This has been a very brief introduction to the problems and design solutions in a persistence framework and service. Many important issues have been glossed over, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 对象非物质化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 简而言之,映射器必须定义 putObjectToStorage 方法。非具体化合成层次结构需要多个映射器之间的协作以及关联表的维护(如果使用 RDB)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • dematerializing objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Briefly, the mappers must define putObjectToStorage methods. Dematerializing composition hierarchies requires collaboration between multiple mappers and the maintenance of associative tables (if an RDB is used).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 藏品的物化和非物质化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • materialization and dematerialization of collections

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 对象组的查询

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • queries for groups of objects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 全面的交易处理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • thorough transaction handling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 数据库操作失败时的错误处理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • error handling when a database operation fails

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 多用户访问和锁定策略

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • multiuser access and locking strategies

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 安全性控制对数据库的访问

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • securitycontrolling access to the database

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第 39 章.记录架构:UML & N+1 View Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Chapter 39. Documenting Architecture: UML & the N+1 View Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  他们有电脑,也可能有其他大规模杀伤性武器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  美国政府官员

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  They have computers, and they may have other weapons of mass destruction.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  USA government official

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 基于 N+1(或 4+1)视图模型创建有用的架构文档。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Create useful architecture documentation based on the N+1 (or 4+1) view model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 应用各种 UML 图类型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Apply various UML diagram types.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    一旦架构形成,描述它可能会很有用,这样新的开发人员就可以了解系统的宏大思想,或者有一个共同的观点来讨论更改。在 UP 中,描述此内容的工件是软件架构文档 (SAD)。本章介绍了 SAD 及其内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Once an architecture takes shape, it may be useful to describe it, so that new developers can learn the big ideas of the system, or so that there is a common view from which to discuss changes. In the UP, the artifact that describes this is the Software Architecture Document (SAD). The chapter introduces the SAD and its contents.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      39.1. SAD 及其架构视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      39.1. The SAD and Its Architectural Views

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Software Architect 文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Software Architect Document

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      除了 UML 包、类和交互图之外,UP 设计模型中的另一个关键工件是 SAD。它描述了架构中的大思想,包括架构分析的决策。实际上,对于需要理解系统基本思想的开发人员来说,它是一个学习辅助工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In addition to the UML package, class, and interaction diagrams, another key artifact in the UP Design Model is the SAD. It describes the big ideas in the architecture, including the decisions of architectural analysis. Practically, it is a learning aid for developers who need to understand the essential ideas of the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SAD 的本质是架构决策(例如技术备忘录)和 N+1 架构视图的摘要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The essence of the SAD is a summary of the architectural decisions (such as with technical memos) and the N+1 architectural views.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      动机:为什么要创建 SAD?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Motivation: Why Create a SAD?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      当有人加入开发团队时,如果项目指导员可以说:“欢迎来到 NextGen 项目!请访问项目网站并阅读十页的 SAD,以便了解大创意。稍后,在后续发布期间,当新人在系统上工作时,SAD 可以成为加快他们理解速度的学习辅助工具。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When someone joins the development team, it's useful if the project coach can say, "Welcome to the NextGen project! Please go to the project website and read the ten page SAD in order to get an introduction to the big ideas." And later, during a subsequent release, when new people work on the system, a SAD can be a learning aid to speed their comprehension.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      因此,在编写它时应该牢记这个受众和目标:我需要说什么(并在 UML 中画出)来帮助人们快速理解这个系统中的主要思想?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Therefore, it should be written with this audience and goal in mind: What do I need to say (and draw in the UML) that will quickly help someone understand the major ideas in this system?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      建筑视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Architectural Views

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      拥有架构是一回事;有用的描述是其他内容。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Having an architecture is one thing; a useful description is something else.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在 [Kruchten95] 中,提出了具有影响力且被广泛采用的描述具有多个视图的架构的想法;它的多视图模型现在被认为是实践的状态。架构视图的基本思想是这样的:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In [Kruchten95], the influential and widely adopted idea of describing an architecture with multiple views was promoted; its multiple-view model is now considered the state of the practice. The essential idea of an architectural view is this:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      定义:架构视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Definition: Architectural View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      从给定角度查看系统架构;它主要关注结构、模块化、基本组件和主要控制流。[RUP] 的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A view of the system architecture from a given perspective; it focuses primarily on structure, modularity, essential components, and the main control flows. [RUP].

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      这个 RUP 定义中缺少的观点的一个重要方面是动机。也就是说,架构视图应该解释为什么架构是这样的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An important aspect of the view missing from this RUP definition is the motivation. That is, an architectural view should explain why the architecture is the way it is.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      架构视图是从特定角度进入系统的窗口,它强调关键的值得注意的信息或想法,而忽略其余部分。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An architectural view is a window onto the system from a particular perspective that emphasizes the key noteworthy information or ideas, and ignores the rest.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      建筑视图是交流、教育或思考的工具;它以文本和 UML 图表示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An architectural view is a tool of communication, education, or thought; it is expressed in text and UML diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      例如,第 34 章中关于分层和逻辑架构的 NextGen 包和交互图显示了软件架构逻辑结构的宏大思想。在 SAD 中,架构师将创建一个名为 Logical View 的部分,插入这些 UML 图,并添加一些关于每个包和层的用途以及逻辑设计背后的动机的书面注释。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For example, the NextGen package and interaction diagrams shown in Chapter 34 on layering and logical architecture show the big ideas of the logical structure of the software architecture. In the SAD, the architect will create a section called Logical View, insert those UML diagrams, and add some written commentary on what each package and layer is for, and the motivation behind the logical design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      具体来说,文本和图表的架构视图的一个关键思想是,它们并不从某个角度描述整个系统,而只是从那个角度描述出色的想法。如果你愿意的话,一个观点就是“一分钟电梯”的描述:从这个角度来看,你会在电梯里对同事说一分钟内最重要的事情是什么?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A key idea of the architectural viewswhich concretely are text and diagramsis that they do not describe all of the system from some perspective, but only outstanding ideas from that perspective. A view is, if you will, the "one-minute elevator" description: What are the most important things you would say in one minute in an elevator to a colleague on this perspective?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      可以通过以下方式创建建筑视图:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Architectural views may be created:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 构建系统后,作为未来开发人员的总结和学习辅助

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • after the system is built, as a summary and learning aid for future developers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 在某些迭代里程碑结束时(例如细化结束),作为当前开发团队和新成员的学习辅助工具

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • at the end of certain iteration milestones (such as the end of elaboration) to serve as a learning aid for the current development team, and new members

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 推测性地,在早期迭代中,作为创造性设计工作的辅助,认识到原始视图将随着设计和实现的进行而改变

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • speculatively, during early iterations, as an aid in creative design work, recognizing that the original view will change as design and implementation proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      N+1(或 4+1)视图模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The N+1 (or 4+1) View Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      在他的开创性论文中,Kruchten 不仅提倡从不同的视图记录架构,而且更具体地说,展示了 4+1 视图,今天它已经更普遍地扩展到 N+1 视图,反映了系统中的无数关注点。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In his seminal paper, Kruchten not only promoted documenting an architecture from different views, but more specifically, showing the 4+1 views, which today has expanded more generally to the N+1 views, reflecting the myriad concerns in a system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      简而言之,本文中描述的 4 个视图是:逻辑、流程、部署和数据。这些将在下一节中介绍。“+1”视图是用例视图,是架构上最重要的用例或场景的摘要,也可能是这些用例实现的摘要。用例视图汇集了一个共同的故事,该故事将对其他视图的理解以及它们如何相互关联联系在一起。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Briefly, the 4 views described in the paper are: logical, process, deployment, and data. These are described in a following section. The '+1' view is the use case view, a summary of the most architecturally significant use cases or scenarios, and perhaps a summary of use-case realizations for these. The use case view pulls together a common story that ties together an understanding of the other views and how they interrelate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      更详细的建筑视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Architectural Views in More Detail

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      无数个视图是可能的,每个视图都反映了一个系统的主要架构观点;以下是常见视图的列表:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Myriad views are possible, each reflecting a major architectural viewpoint on to a system; here is a list of common views:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. 逻辑

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 软件在最重要的层、子系统、包、框架、类和接口方面的概念组织。此外,还总结了主要软件元素的功能,例如每个子系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 显示出色的用例实现场景(如交互图),用于说明系统的关键方面。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UP Design Model 的视图,使用 UML 包、类和交互图进行可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. Logical

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Conceptual organization of the software in terms of the most important layers, subsystems, packages, frameworks, classes, and interfaces. Also summarizes the functionality of the major software elements, such as each subsystem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Shows outstanding use-case realization scenarios (as interaction diagrams) that illustrate key aspects of the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A view onto the UP Design Model, visualized with UML package, class, and interaction diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. 过程

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 进程和线程。他们的职责、协作以及逻辑元素(层、子系统、类等)的分配。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UP Design Model 的视图,使用 UML 进程和线程表示法通过 UML 类和交互图进行可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4. Process

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Processes and threads. Their responsibilities, collaborations, and the allocation of logical elements (layers, subsystems, classes, …) to them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A view onto the UP Design Model, visualized with UML class and interaction diagrams, using the UML process and thread notation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      5. 部署

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 将进程和组件物理部署到处理节点,以及节点之间的物理网络配置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UP 部署模型的视图,使用 UML 部署图进行可视化。通常,“视图” 只是整个模型而不是子集,因为它都值得注意。有关 UML 部署图表示法,请参见第 37 章

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      6. Deployment

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Physical deployment of processes and components to processing nodes, and the physical network configuration between nodes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A view onto the UP Deployment Model, visualized with UML deployment diagrams. Normally, the "view" is simply the entire model rather than a subset, as all of it is noteworthy. See Chapter 37 for the UML deployment diagram notation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      7. 数据

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 数据流概述、持久数据架构、从对象到持久数据(通常在关系数据库中)的架构映射、从对象映射到数据库的机制、数据库存储过程和触发器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 在某种程度上,UP 数据模型的视图,使用用于描述数据模型的 UML 类图进行可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 数据流可以用 UML 活动图来显示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      8. Data

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Overview of the data flows, persistent data schema, the schema mapping from objects to persistent data (usually in a relational database), the mechanism of mapping from objects to a database, database stored procedures and triggers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • In part, a view onto the UP Data Model, visualized with UML class diagrams used to describe a data model.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Data flows can be shown with UML activity diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      9. 安全

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 安全方案的概述,以及体系结构中应用安全性的点,例如 HTTP 身份验证、数据库身份验证等。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 可以是 UP 部署模型的视图,通过突出显示安全关键点的 UML 部署图和相关文件进行可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      10. Security

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Overview of the security schemes, and points within the architecture that security is applied, such as HTTP authentication, database authentication, and so forth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Could be a view onto the UP Deployment Model, visualized with UML deployment diagrams that highlight the key points of security, and related files.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      11. 实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 首先,实现模型的定义:与其他 UP 模型(文本和图表)相比,这个“模型”实际的源代码、可执行文件等。它有两个部分:1) 可交付成果,以及 2) 创建可交付成果的东西(比如源代码和图形)。实现模型是所有这些内容,包括 Web 页面、DLL、可执行文件、源代码等,以及它们的组织,例如 Java 包中的源代码和组织到 JAR 文件中的字节码。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 实现视图是对值得注意的交付项组织和创建交付项的事物 (例如源代码) 的摘要描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UP 实现模型的视图,以文本表示,并通过 UML 包和组件图进行可视化。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      12. Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • First, a definition of the Implementation Model: In contrast to the other UP models, which are text and diagrams, this "model" is the actual source code, executables, and so forth. It has two parts: 1) deliverables, and 2) things that create deliverables (such as source code and graphics). The Implementation Model is all of this stuff, including Web pages, DLLs, executables, source code, and so forth, and their organizationsuch as source code in Java packages, and bytecode organized into JAR files.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The implementation view is a summary description of the noteworthy organization of deliverables and the things that create deliverables (such as the source code).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A view onto the UP Implementation Model, expressed in text and visualized with UML package and component diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      13. 发展

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 此视图汇总了开发人员需要了解的有关开发环境设置的信息。例如,所有文件如何按目录组织,为什么?构建和冒烟测试如何运行?如何使用版本控制?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      14. Development

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • This view summarizes information developers need to know about the setup of the development environment. For example, how are all the files organized in terms of directories, and why? How does a build and smoke test run? How is version control used?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      15. 用例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 架构上最重要的用例及其非功能性要求的摘要。也就是说,那些通过实现说明重要的架构覆盖范围或练习许多架构元素的用例。例如,完全实施后,Process Sale 用例具有这些品质。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • UP 用例模型的视图,以文本表示,并通过 UML 用例图可视化,可能还有 UML 交互图中的用例实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      16. Use case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Summary of the most architecturally significant use cases and their non-functional requirements. That is, those use cases that, by their implementation, illustrate significant architectural coverage or that exercise many architectural elements. For example, the Process Sale use case, when fully implemented, has these qualities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • A view onto the UP Use-Case Model, expressed in text and visualized with UML use case diagrams and perhaps with use-case realizations in UML interaction diagrams.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      指南:不要忘记动力!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Guideline: Don't Forget the Motivation!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      每个视图不仅包括图表,还包括扩展和阐明的文本。在这个散文部分,一个经常被遗忘但非常重要的部分是讨论动机。为什么安全性是这样的?为什么将三个主要软件组件部署在两台计算机上,而不是三台计算机上?事实上,当需要对架构进行重大更改时,这一部分通常比其他任何部分都更重要。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Each view includes not only diagrams, but text that expands and clarifies. In this prose section, an often forgotten but tremendously important section is to discuss the motivation. Why is the security the way it is? Why are the three major software components deployed on two computers rather than three? Indeed, this section often becomes more important than any other when it comes time to make significant changes to the architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        39.2. 符号:SAD 的结构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        39.2. Notation: The Structure of a SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        以下 SAD 结构本质上是 UP 中使用的格式:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The following SAD structure is essentially the format used in the UP:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        软件架构文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Software Architecture Document

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        建筑表示

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Architectural Representation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (本文档中将如何描述体系结构的摘要,例如按技术备忘录和体系结构视图使用。这对于不熟悉技术备忘录或视图概念的人来说很有用。请注意,并非所有视图都是必需的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (Summary of how the architecture will be described in this document, such as using by technical memos and the architectural views. This is useful for someone unfamiliar with the idea of technical memos or views. Note that not all views are necessary.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        架构因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (请参考补充规范查看因子表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (Reference to the Supplementary Specification to view the Factor Table.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        架构决策

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Architectural Decisions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (总结决策的技术备忘录集。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (The set of technical memos that summarize the decisions.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        逻辑视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Logical View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        UML 包图和主要元素的类图。对主要组件的大规模结构和功能的评论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (UML package diagrams, and class diagrams of major elements. Commentary on the large scale structure and functionality of major components.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        部署视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Deployment View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        显示节点以及进程和组件分配的 UML 部署图。对网络的评论。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (UML deployment diagrams showing the nodes and allocation of processes and components. Commentary on the networking.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        进程视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Process View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        说明系统进程和线程的 UML 类和交互图。按交互的线程和进程对此进行分组。评论进程间通信的工作原理(例如,通过 Java RMI)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (UML class and interaction diagrams illustrating the processes and threads of the system. Group this by threads and processes that interact. Comment on how the interprocess communication works (e.g., by Java RMI).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        用例视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Use-Case View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (架构上最重要的用例的简要总结。 用于某些体系结构重要用例实现或场景的 UML 交互图,并对图表进行注释,解释它们如何说明主要体系结构元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        (Brief summary of the most architecturally significant use cases. UML interaction diagrams for some architectural significant use-case realizations, or scenarios, with commentary on the diagrams explaining how they illustrate the major architectural elements.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        其他视图...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Other Views…



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          39.3. 示例:NextGen POS SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          39.3. Example: A NextGen POS SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在这个和后续的例子中,我的目标不是详尽地展示一个完整的 10+ 页 SAD,并带有完全描述性的文本和详细的图表,而是给出可能包含的内容的味道。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In this and subsequent examples, my goal is not to exhaustively show a thorough 10+ page SAD with fully descriptive text and detailed diagrams, but to give a flavor of what may be included.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          软件架构文档:NextGen POS 项目

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Software Architecture Document: NextGen POS Project

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          简介:建筑表示

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introduction: Architectural Representation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          此 SAD 从多个视图总结了体系结构。这些包括:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This SAD summarizes the architecture from multiple views. These include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 逻辑视图: ...简要定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • logical view: …brief definition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 数据视图: ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • data view: …

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 进程视图:...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • process view: …

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          此外,此 SAD 还引用了补充规范,您可以在其中找到因子表中记录的架构重要要求。它还以一种称为技术备忘录的格式总结了关键的架构决策,这是决策及其动机的简短单页描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In addition, this SAD references the Supplementary Specification where you will find the architecturally-significant requirements recorded in a factor table. It also summarizes the key architectural decisions in a format called a technical memoa short one-page description of a decision and its motivation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请注意,每个视图都包含对动机的讨论,这可能有助于您何时需要修改体系结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Note that each view includes a discussion of motivation, which may help you when you need to modify the architecture.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          请参阅从第 548 页开始的架构重要要求的补充规范因子表。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          See the Supplementary Specification factor table of architecturally-significant requirements starting on p. 548.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          架构决策(技术备忘录)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Architectural Decisions (Technical Memos)



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          技术备忘录:问题:可靠性从远程服务故障中恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Technical Memo: Issue: ReliabilityRecovery from Remote Service Failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          解决方案摘要:使用服务查找、从远程到本地的故障转移以及本地服务部分复制实现位置透明。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution Summary: Location transparency using service lookup, failover from remote to local, and local service partial replication.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 从远程服务故障(例如,税收计算器、库存)中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Robust recovery from remote service failure (e.g., tax calculator, inventory)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 从远程产品(例如描述和价格)数据库故障中稳健恢复

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Robust recovery from remote product (e.g., descriptions and prices) database failure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          溶液

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          使用在 ServicesFactory 中创建的 Adapter 实现服务位置的受保护变体。在可能的情况下,提供远程服务的本地实现,通常具有简化或约束的行为。例如,当地税计算器将使用固定税率。本地产品信息数据库将是最常见产品的一小块缓存。库存更新将在重新连接时存储和转发。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Achieve protected variation with respect to location of services using an Adapter created in a ServicesFactory. Where possible, offer local implementations of remote services, usually with simplified or constrained behavior. For example, the local tax calculator will use constant tax rates. The local product information database will be a small cache of the most common products. Inventory updates will be stored and forwarded at reconnection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          另请参阅适应性第三方服务技术备忘录,了解此解决方案的适应性方面,因为远程服务实施在每次安装时都会有所不同。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          See also the AdaptabilityThird-Party Services technical memo for the adaptability aspects of this solutions, because remote service implementations will vary at each installation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          为了满足尽快与远程服务重新连接的质量方案,请对服务使用智能代理对象,在每次服务调用时测试远程服务重新激活,并在可能的情况下重定向到它们。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          To satisfy the quality scenarios of reconnection with the remote services ASAP, use smart Proxy objects for the services, that on each service call test for remote service reactivation, and redirect to them when possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          赋予动机

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          零售商真的不想停止销售!因此,如果 NextGen POS 提供这种级别的可靠性和恢复能力,它将是一款非常有吸引力的产品,因为我们的竞争对手都没有提供这种功能。小型产品缓存是由非常有限的客户端资源驱动的。真正的第三方税务计算器不会在客户端上复制,主要是因为许可成本和配置工作较高(因为每个计算器安装几乎每周都需要调整一次)。这种设计还支持未来客户的演变点,他们愿意并能够将税收计算器等服务永久复制到每个客户端。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Retailers really don't want to stop making sales! Therefore, if the NextGen POS offers this level of reliability and recovery, it will be a very attractive product, as none of our competitors provide this capability. The small product cache is motivated by very limited client-side resources. The real third-party tax calculator is not replicated on the client primarily because of the higher licensing costs, and configuration efforts (as each calculator installation requires almost weekly adjustments). This design also supports the evolution point of future customers willing and able to permanently replicate services such as the tax calculator to each client terminal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          未解决的问题无

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Unresolved Issuesnone

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          考虑的替代方案

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Alternatives Considered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “黄金级”服务质量协议,提供远程信用授权服务,以提高可靠性。它可用,但太贵了。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A "gold level" quality of service agreement with remote credit authorization services to improve reliability. It was available, but much too expensive.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          技术备忘录:问题:法律税务规则合规性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Technical Memo: Issue: LegalTax Rule Compliance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          解决方案摘要:购买税计算器组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Solution Summary: Purchase a tax calculator component.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因素 ...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 1.逻辑视图的包图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          讨论和激励

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discussion and Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          使用经典的分层架构。在 UI 层和域层之间没有插入会话对象的应用程序层,因为系统操作很简单,没有太多的工作流程协调。从 UI 层接收系统操作请求的主要控制器是 Register 类。请注意,门面放置在对 Jess 规则引擎的访问前面,因为我们将来可能希望使用替代方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A classic layered architecture is used. No application layer of sessions objects was inserted between the UI and Domain layers, as the system operations are simple, without much workflow coordination. The primary controller receiving the system operation requests from the UI layer is the Register class. Note that a facade is placed in front of access to the Jess rule engine as we may wish to use an alternative in the future.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 2.Deployment 视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          讨论和激励

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discussion and Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          产品数据库、库存系统和税收计算器部署到不同的计算机上,以实现性能和可靠性目标。税收计算器是集中的,而不是在每个 POS 终端上复制,因为它的许可成本很高;将来有可能在每个 POS 终端上本地复制的成本足够低。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The product database, inventory system, and tax calculator are deployed to different computers for performance and reliability goals. The tax calculator is centralized, rather than replicated on each POS terminal, because of its high licensing cost; there is a chance that in the future it will be inexpensive enough to replicate locally on each POS terminal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          数据视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Data View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          讨论和激励

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discussion and Motivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          流程销售用例场景是了解主要数据流的一个很好的示例。UML 活动图以数据流风格应用,以说明主要流和数据存储。参见图 3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A Process Sale use case scenario is a good example to understand the major data flows. A UML activity diagram is applied in a data-flow flavor to illustrate the major flows and data stores. See Figure 3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 3.流程销售场景的数据流视图。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          从 Products 数据库读取的数据到 Java 对象的转换是通过 Hibernate O-R 映射系统完成的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Transformation of data read from the Products database into Java objects is done with the Hibernate O-R mapping system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          写入 ERP 数据库(库存和会计)的销售数据由自定义 NextGen 适配器完成,通常转换为 ERP 系统所需的 XML 格式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Transformation of sale data written to the ERP databases (inventory and accounting) is done by a custom NextGen adapter, usually into an XML format required by the ERP system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          发送到外部支付授权服务的支付请求数据的转换由自定义 NextGen 适配器完成,通常转换为众所周知的 VISA 格式(和协议)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Transformation of the payment request data sent to the external payment authorization service is done by a custom NextGen adapter, usually into the well-known VISA format (and protocol).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          赋予动机?这些外部系统和数据库是我们必须遵守的硬性约束。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Motivation? These external systems and databases were a hard constraint that we had to conform to.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          用例视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Use-Case View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在架构上最重要的用例是 Process Sale。请参阅从第 67 页开始的用例文本。通过实施此用例,大多数关键的架构问题都得到了解决。一个关键的系统操作是 enterItem;参见图 4 中一些值得注意的逻辑边界的部分交互场景。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The most architecturally significant use case is Process Sale. See the use-case text starting on p. 67. By implementing this use case, most of the key architectural issues were confronted and resolved. A key system operation is enterItem; see Figure 4 for a partial interaction scenario across some noteworthy logical boundaries.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 3.流程销售场景中的部分用例实现。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          其他视图...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Other Views



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            39.4. 示例:Jakarta Struts SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            39.4. Example: A Jakarta Struts SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts 是一种流行的开源 Java 技术框架,用于处理 Web 请求和页面流协调。在这个例子中,部分 SAD,我想更详细地说明一个逻辑视图。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts is a popular open source Java technology framework for handling Web requests and page-flow coordination. In this example, partial SAD, I wish to illustrate a logical view in more detail.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            软件架构文档:Jakarta Struts 框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Software Architecture Document: Jakarta Struts Framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            建筑表示

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural Representation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            架构因素

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural Factors

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            架构决策

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural Decisions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            逻辑视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Logical View

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts 框架和使用它构建的子系统主要驻留在 Web 应用程序的 UI 层中。图 1 显示了带有 UML 包图的值得注意的层和包。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Struts frameworkand subsystems built with itreside primarily in the UI layer of a web application. Figure 1 illustrates noteworthy layers and packages with a UML package diagram.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 1.与 Struts 相关的值得注意的层和包。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            纯 UI 层职责(包括创建要显示的内容和页面)与有时称为应用程序控制层(负责决定控制流并指示表示层显示某些内容的组件层)之间存在差异。在通常的使用中,Web 表示框架通常意味着包含应用程序控制职责,Struts 也是如此,因为它要求开发人员创建负责流控制决策的 Struts Action 类的子类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            There is a distinction between pure UI layer responsibilities, that encompass creating the content and pages for display, vs. what is sometimes called the application control layerthe layer of components that is responsible for deciding the flow of control, and directing the presentation layer to display something. In common use, web presentation frameworks usually imply the inclusion of application control responsibilities, which is also true of Struts, as it requires developers to create subclasses of the Struts Action class that are responsible for flow control decisions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            架构模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Architectural Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts 架构基于模型-视图-控制器 (MVC) 模式;具体来说,组件角色所在的 Web 系统变体:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Struts architecture is based on the Model-View-Controller (MVC) pattern; specifically, the web systems variant where the component roles are:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            控制器 一个多线程单例 Facade 类对象,负责接收和委托 HTTP 请求,并通过与其他对象协作来控制应用程序的流。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Controller a multithreaded singleton Facade-like object responsible for receiving and delegating HTTP requests, and by collaboration with other objects, controlling the flow of the application.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            查看负责生成显示内容(例如 HTML)的组件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            View components responsible for generating display content (e.g., HTML).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            负责域逻辑和状态的组件进行建模。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Model components responsible for domain logic and state.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts 采用 MVC 为实现与流控制、显示内容生成(和格式设置)相关的关注点分离提供了架构基础,在这种情况下,通过模块化为单独的组件组,这些组件组专门负责紧密相关的职责。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts adoption of MVC provides the architectural foundation to achieve a separation of concerns related to flow control, display content generation (and formatting), and application logicin this case through modularization into separate component groups that specialize by cohesively related responsibilities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 2 中的 UML 类图说明了映射到 Struts 组件的特定 MVC 角色。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The specific MVC roles mapped to Struts components is illustrated in the UML class diagram in Figure 2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 2.Struts 中的 MVC 角色。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            相关模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Related Patterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ActionServlet 充当表示层上的 Facade。虽然它不是接收和调解其他解耦对象之间的消息传递的经典 Mediator,但它是相似的,因为 Action 对象将 ActionForward 对象返回给 ActionServlet,该对象用于指导下一步。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The ActionServlet acts as a Facade onto the presentation layer. And although not a classic Mediator that receives and mediates messaging between other decoupled objects, it is similar, because an Action object returns an ActionForward object to the ActionServlet, which is used to direct the next step.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts ActionServlet 和 Action 设计还说明了命令处理器模式,它是 GoF Command 设计模式的变体。ActionServlet 扮演命令处理器的角色,接收请求并将其映射到执行请求的 Action (Command) 对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Struts ActionServlet and Action design also illustrates the Command Processor pattern, a variant of the GoF Command design pattern. The ActionServlet plays the role of Command Processor, receiving requests and mapping them to Action (Command) objects that execute requests.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts 演示了 Front Controller 和 Business Delegate 模式。ActionServlet 是前端控制器,或处理请求的初始联系点。Action 对象是业务委托抽象,委托给服务的 “业务” 或域层。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Struts demonstrates the Front Controller and Business Delegate patterns. The ActionServlet is the Front Controller, or initial point of contact for handling requests. The Action objects are Business Delegates-abstractions that delegate to the "business" or domain layer of services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Action 对象还扮演 Adapter 的角色,使框架调用适应域层对象的接口。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Action objects also play the role of Adapters, adapting the framework calls to the interface of the domain layer objects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            如图 3 所示,ActionServlet 实现了 Template Method 模式:process 是模板,processXXX 是钩子方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            As illustrated in the Figure 3, the ActionServlet implements the Template Method pattern: process is the template, and the processXXX are the hook methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 3.Struts 框架热点。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            框架热点

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Framework Hotspots

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            使用框架的关键是了解它的热点框架中的变体点,开发人员可以通过子类化、基于接口的组合以及通常在配置文件中外部化的声明性约束或映射等技术来参数化或“插入”特定于应用程序的变化行为。图 3 说明了关键的 Struts 热点,它们使用子类化和声明式映射,这是白盒框架设计的典型特征。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Key to using a framework is knowing its hotspotsthe variation points in the framework where the devel oper can parameterize or "plug in" applications-specific varying behavior, through techniques such as subclassing, composition based on interfaces, and declarative constraints or mappings usually externalized in configuration files. Figure 3 illustrates key Struts hotspots, which use subclassing and declarative mappings, typical of whitebox framework designs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            其他视图...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Other Views



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              39.5. 过程:迭代架构文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              39.5. Process: Iterative Architectural Documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UP 和 SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UP and the SAD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              初始如果不清楚在技术上是否可能满足架构上重要的要求,团队可以实施架构概念验证 (POC) 来确定可行性。在 UP 中,它的创建和评估称为 Architectural Synthesis。这与针对孤立技术问题的普通小型 POC 编程实验不同。架构 POC 略微涵盖了许多架构上重要的要求,以评估它们的组合可行性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Inception If it is unclear whether it is technically possible to satisfy the architecturally significant requirements, the team may implement an architectural proof-of-concept (POC) to determine feasibility. In the UP, its creation and assessment is called Architectural Synthesis. This is distinct from plain old small POC programming experiments for isolated technical questions. An architectural POC lightly covers many of the architecturally significant requirements to assess their combined feasibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              阐述此阶段的一个主要目标是实现核心风险架构元素,因此大多数架构分析都是在细化过程中完成的。通常预计大部分因子表、技术备忘录和 SAD 内容可以在阐述结束时完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Elaboration A major goal of this phase is to implement the core risky architectural elements, thus most architectural analysis is completed during elaboration. It is normally expected that the majority of factor table, technical memo, and SAD content can be completed by the end of elaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              过渡尽管理想情况下,架构上重要的因素和决策在过渡之前很久就已经解决了,但 SAD 需要在此阶段结束时进行审查和可能的修订,以确保它准确描述最终部署的系统。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Transition Although ideally the architecturally significant factors and decisions were resolved long before transition, the SAD will need a review and possible revision at the end of this phase to ensure it accurately describes the final deployed system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              后续的进化周期在设计新版本之前,通常会重新审视架构因素和决策。例如,版本 1.0 中决定创建一个远程税务计算器服务,而不是在每个 POS 节点上复制一个服务,这可能是出于成本(以避免多个许可证)。但也许将来税收计算器的成本会降低,因此,出于容错或性能原因,架构会更改为使用多个本地税收计算器。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Subsequent evolution cycles Before the design of new versions, it is common to revisit architectural factors and decisions. For example, the decision in version 1.0 to create a single remote tax calculator service, rather than one duplicated on each POS node, could have been motivated by cost (to avoid multiple licenses). But perhaps in the future the cost of tax calculators is reduced, and thus, for fault tolerance or performance reasons, the architecture is changed to use multiple local tax calculators.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                39.6. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                39.6. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                除了原始论文 [Kruchten95] 之外,Clements 等人的 Documenting Software Architectures: Views and Beyond 也是一个有用的资源。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In addition to the original paper [Kruchten95], Documenting Software Architectures: Views and Beyond by Clements, et al. is a useful resource.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  第 40 章.有关迭代开发和敏捷项目管理的更多信息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Chapter 40. More on Iterative Development and Agile Project Management

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  预测非常困难,尤其是当它关乎未来时。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  匿名

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Prediction is very difficult, especially if it's about the future.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  anonymous

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  目标

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Objectives

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 对要求和风险进行排名。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Rank requirements and risks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 比较和对比自适应规划和预测性规划。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Compare and contrast adaptive and predictive planning.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    介绍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Introduction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    迭代和敏捷项目规划和管理问题是大话题,但简要探讨与迭代开发和 UP 相关的一些关键问题是有帮助的,例如:下一次迭代要做什么?迭代开发中如何跟踪需求?如何组织项目工件?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Iterative and agile project planning and management issues are large topics, but a brief exploration of some key questions related to iterative development and the UP is helpful, such as: What to do in the next iteration? How to track requirements in iterative development? How to organize project artifacts?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      40.1. 如何计划迭代?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      40.1. How to Plan an Iteration?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      方法有很多种,但以下比较典型:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There are many approaches, but the following is relatively typical:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第一步是确定迭代的长度;26 周是常见的范围。一般来说,越短越好。延长迭代的因素包括具有高度发现和更改的早期工作、大型团队和分布式团队。回想一下,一旦选择了结束日期,它就必须保持固定,这就是时间盒的做法。但是,可以缩小迭代的工作范围以满足结束日期。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      第二步是召开迭代规划会议。这通常在当前迭代结束时完成,例如在最后一个星期五,在星期一开始下一个迭代的工作之前。理想情况下,大多数利益相关者都出席了会议:客户(营销、用户等)、开发人员、首席架构师、项目经理。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      给出了迭代的潜在目标(新功能或用例、缺陷等)列表,按某个优先级方案排序(参见第 130 页)。目标列表通常来自客户 (业务目标) 和首席架构师 (技术目标)。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      团队的每个成员都会被要求提供迭代的个人资源预算(以小时或天为单位);例如,人们知道他们将在某些日子外出度假,等等。所有资源预算相加。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      5.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      对于一个目标(例如用例),会对其进行一些详细描述,并解决问题。然后,要求会议成员(尤其是开发人员)集思广益,为目标制定一组更详细的任务,并进行一些模糊的估计。例如,UI 任务、数据库任务、域层 OO 开发任务、外部系统集成任务等。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 所有任务估计值都汇总为一个运行总计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • All the task estimates are summed into a running total.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      6.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      步骤 #5 重复,直到选择足够的工作:迭代任务总数除以资源预算总额。如果给定可用资源和迭代的时间盒截止日期,工作非常吻合,则会议结束。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      请注意,在这种 “敏捷项目管理” 方法中,开发人员是参与规划和估算过程的活动,而不是由项目经理交给一组任意的目标、估计和截止日期。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Notice in this "agile project management" approach that the developers are activity involved in the planning and estimating process, rather than being handed by the project manager an arbitrary set of goals, estimates, and deadlines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        40.2. 自适应规划与预测规划

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        40.2. Adaptive versus Predictive Planning

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        迭代开发的一大理念是根据反馈进行调整,而不是试图详细预测和规划整个项目。因此,在 UP 中,只为下一次迭代创建一个迭代计划。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        One of the big ideas of iterative development is to adapt based on feedback, rather than to attempt to predict and plan in detail the entire project. Consequently, in the UP, one creates an Iteration Plan for only the next iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在下一次迭代之后,详细的计划是开放的,以便随着未来的展开而自适应地调整(见图 40.1)。除了鼓励灵活的、机会主义的行为之外,不详细规划整个项目的一个简单原因是,在迭代开发中,并非所有需求、设计细节和步骤在项目开始时都是已知的。[1] 另一个是他们更喜欢相信团队在进行过程中的规划判断。最后,假设在项目开始时制定了一个细粒度的详细计划,并且团队“偏离”了它,以更好地洞察如何最好地运行项目。从外部来看,这可能被视为某种失败,而实际上恰恰相反。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Beyond the next iteration the detailed plan is left open, to adaptively adjust as the future unfolds (see Figure 40.1). In addition to encouraging flexible, opportunistic behavior, one simple reason for not planning the entire project in detail is that in iterative development not all the requirements, design details, and thus steps are known near the start of the project.[1] Another is the preference to trust the planning judgement of the team as they proceed. Finally, suppose there was a fine-grained detailed plan laid out at the start of the project, and the team "deviates" from it to exploit better insight in how to best run the project.n From the outside, this might be viewed as some kind of failure, when it in fact it is just the opposite.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] 他们在 “瀑布 ”项目中也不是真正或可靠的,尽管整个项目的详细规划可能会像他们一样进行。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        [1] They aren't really or reliably known on a "waterfall" project either, although detailed planning for the entire project may occur as though they were.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        图 40.1.里程碑很重要,但要避免对遥远的未来进行详细的预测规划。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        但是,仍然目标和里程碑;适应性开发并不意味着团队不知道他们要去哪里,也不知道里程碑日期和目标。在迭代开发中,团队仍然会承诺日期和目标,但实现这些目标的详细路径是灵活的。例如,NextGen 团队可能会设定一个里程碑,在三个月内,用例 Process Sale、Handle ReturnsAuthenticate User,以及日志记录和可插拔规则功能将完成。但是,这是关键点:到该里程碑的两周时间盒迭代的细粒度计划或路径没有详细定义。步骤的顺序或在接下来的三个月中每次迭代中要做什么,都不是固定的。相反,只计划下一个为期两周的迭代,团队逐步适应,努力在里程碑日期之前实现目标。当然,组件和资源中的依赖关系自然会限制工作的某些顺序,但并非所有活动都需要细粒度地进行规划和调度。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        However, there are still goals and milestones; adaptive development doesn't mean the team doesn't know where they are going, or the milestone dates and objectives. In iterative development, the team still does commit to dates and objectives, but the detailed path to these is flexible. For example, the NextGen team may set a milestone that in three months, use cases Process Sale, Handle Returns, and Authenticate User, and the logging and pluggable rules features will be completed. Butand this is the key pointthe fine-grained plan or path of two-week timeboxed iterations to that milestone is not defined in detail. The order of steps, or what to do in each iteration over the following three months, is not fixed. Rather, just the next two-week iteration is planned, and the team adapts step by step, working to fulfill the objectives by the milestone date. Of course, dependencies in components and resources naturally constrain some ordering of the work, but not all activities need to be planned and scheduled in fine-grained detail.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        外部利益相关者会看到一个宏观级别的计划(例如三个月级别),团队对该计划做出了一些承诺。但是微观层面的组织由团队的最佳和适应性判断决定,因为它利用了新的见解(见图 40.1)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        External stakeholders see a macro-level plan (such as at the three-month level) to which the team makes some commitment. But the micro-level organization is left up to the bestand adaptivejudgment of the team, as it takes advantage of new insights (see Figure 40.1).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        最后,尽管自适应细粒度规划在 UP 中是首选,但随着需求和架构的稳定、团队的成熟以及收集有关开发速度的数据,成功规划两到三次迭代(不可靠性程度越来越高)的可能性越来越大。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Finally, although adaptive fine-grained planning is preferred in the UP, it is increasingly possible to successfully plan forward two or three iterations (with increasingly levels of unreliability) as the requirements and architecture stabilize, the team matures, and data is collected on the speed of development.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          40.3. 阶段和迭代计划

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          40.3. Phase and Iteration Plans

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在宏观层面上,可以建立里程碑日期和目标,但在微观层面上,里程碑的计划是灵活的,除了不久的将来(例如,接下来的四周)。这两个级别反映在 UP 阶段计划和迭代计划中,两者都是复合软件开发计划的一部分。阶段计划列出了宏观层面的里程碑日期和目标,例如阶段结束和中期试点测试里程碑。迭代计划定义当前和下一次迭代的工作,而不是所有迭代(参见图 40.2)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          At a macro level, it is possible to establish milestone dates and objectives, but at the micro level, the plan to the milestone is left flexible except for the near future (for example, the next four weeks). These two levels are reflected in the UP Phase Plan and Iteration Plan, both of which are part of the composite Software Development Plan. The Phase Plan lays out the macro-level milestone dates and objectives, such as the end of phases and mid-phase pilot test milestones. The Iteration Plan defines the work for the current and next iterationnot all iterations (see Figure 40.2).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          图 40.2.阶段和迭代计划。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          在开始时,阶段计划中的里程碑估计是模糊的“猜测”。随着细化的进行,估计数会有所改进。细化阶段的一个目标是,在完成时,为团队提供足够的现实信息,以承诺结束建设和过渡(即项目交付)的主要里程碑日期和目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          During inception, the milestone estimates in the Phase Plan are vague "guesstimates." As elaboration progresses, the estimates improve. One goal of the elaboration phase is, at its completion, to have enough realistic information for the team to commit to major milestone dates and objectives for the end of construction and transition (that is, project delivery).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            40.4. 如何使用用例和场景规划迭代?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            40.4. How to Plan Iterations with Use Cases and Scenarios?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            UP 是用例驱动的,这在一定程度上意味着工作是围绕用例完成来组织的。也就是说,分配一个迭代来实现一个或多个用例,或者如果整个用例太复杂而无法在一次迭代中完成,则分配一个用例的场景。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The UP is use-case driven, which in part implies that work is organized around use-case completion. That is to say, an iteration is assigned to implement one or more use cases, or scenarios of use cases in the case that the complete use case is too complex to complete in one iteration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            最后一点很重要:一个用例通常有太多不同的场景,无法在一个简短的迭代中完成所有场景。因此,工作单元通常是一个场景,而不是一个完整的用例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            This last point is important: It is common that a use case has too many varying scenarios to complete all in one short iteration. Thus typically the unit of work is a scenario, rather than a complete use case.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            由于工作单元可能是一个场景而不是整个用例,因此需求排序(参见第 130 页)可以用场景来完成。这就提出了用例驱动迭代开发中的一个常见问题:如何标记场景?答案:使用 full-dressed 格式的 Cockburn 格式编码方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Since the unit of work may be a scenario rather than an entire use case, requirements ranking (see p. 130) may be done with scenarios. This raises a common question in use-case driven iterative development: How to label scenarios? Answer: Use the Cockburn-format coding scheme in the fully-dressed format.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            例如,请考虑以下用例片段:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            For example, consider the following use case fragment:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            用例:流程销售

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Use Case: Process Sale

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            主要成功情境

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Main Success Scenario:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. 客户到达 POS 收银台时,携带要购买的商品和/或服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2. Customer arrives at POS checkout with goods and/or services to purchase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            3. 出纳开始新的销售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            4. Cashier starts a new sale.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            5. 收银员输入商品标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            6. Cashier enters item identifier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7. 系统记录销售行项目并显示项目描述、价格和汇总。根据一组价格规则计算出的价格。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            8. System records sale line item and presents item description, price, and running total. Price calculated from a set of price rules.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            收银员重复步骤 3-4,直到指示完成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Cashier repeats steps 3-4 until indicates done.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. 系统显示计算税款的总额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2. System presents total with taxes calculated.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            3. 收银员告诉客户总数,并要求付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            4. Cashier tells Customer the total, and asks for payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            5. 客户付款,系统处理付款。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            6. Customer pays and System handles payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            扩展 (或替代流):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Extensions (or Alternative Flows):

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7a.现金支付:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. 出纳输入支付的现金金额。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2. 系统显示到期余额,并释放银箱。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            3. 出纳将现金存入客户,并将余额退还给客户。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            4. 系统记录现金支付。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7b.通过信用卡支付:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. 客户输入其信用账户信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7c.通过支票付款...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7d.通过借记卡付款...

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7a. Paying by cash:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. Cashier enters the cash amount tendered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            2. System presents the balance due, and releases the cash drawer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            3. Cashier deposits cash tendered and returns balance in cash to Customer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            4. System records the cash payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7b. Paying by credit:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            1. Customer enters their credit account information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7c. Paying by check…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            7d. Paying by debit…



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            包括 “Pay by credit” 的 Process Sale 方案可以标记为 “Process Sale-7b”。此方案标签可用作工作单元的排名、跟踪和报告。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The scenario of Process Sale that includes "paying by credit" can be labeled "Process Sale-7b." This scenario label can be used in ranking, tracking, and reporting as a unit of work.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            需求排序指导早期作品的选择。例如,Process Sale 用例显然很重要。因此,我们在第一次迭代中开始处理它。然而,并非所有 Process Sale 的场景都在第一次迭代中实现。相反,选择一些简单、快乐的路径场景,例如 “Process Sale-7a”。尽管该方案很简单,但其实现开始开发设计的一些核心元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The ranking of requirements guides the choice of early work. For example, the Process Sale use case is clearly important. Therefore, we start to tackle it in the first iteration. Yet, not all scenarios of Process Sale are implemented in the first iteration. Rather, some simple, happy path scenario, such as "Process Sale-7a" is chosen. Although the scenario is simple, its implementation starts to develop some core elements of the design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            由于某些需求不是作为用例表示的,而是作为缺陷修复或功能(如日志记录或可插拔业务规则)而这些也被分配给一个或多个迭代。因此,场景、用例、缺陷修复和功能的开发如图 40.3 所示。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Since some requirements are not expressed as use cases, but rather as defect-fixes or featuressuch as logging or pluggable business rulesthese too are allocated to one or more iterations. Thus, development of scenarios, use cases, defect-fixes, and features proceeds as in Figure 40.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            图 40.3.分配给迭代的 Work。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            在细化迭代期间,将处理与此用例相关的不同架构重要需求,迫使团队触及架构的许多方面:主要层、数据库、用户界面、主要子系统之间的接口等。这导致了在系统的许多部分早期创建一个 “广泛而浅层” 的实现,这是细化阶段的共同目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Different architecturally significant requirements related to this use case will be tackled during the elaboration iterations, forcing the team to touch on many aspects of the architecture: the major layers, the database, the user interface, the interfaces between major subsystems, and so forth. This leads to the early creation of a "wide and shallow" implementation across many parts of the systema common goal in the elaboration phase.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              40.5. 早期估计的(不)有效性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              40.5. The (In)Validity of Early Estimates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              垃圾进,垃圾出。使用不可靠和模糊的信息完成的估计是不可靠和模糊的。在 UP 中,可以理解在开始时所做的估计是不可靠的(所有方法都是如此,但 UP 承认这一点)。如果项目值得在细化中进行一些真正的调查,则早期的开始估计仅提供指导,以产生一个好的估计。在第一次细化迭代之后,有一些现实的信息可以产生粗略的估计。在第二次迭代之后,估计开始产生可信度(见图 40.4)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Garbage in, garbage out. Estimates done with unreliable and fuzzy information are unreliable and fuzzy. In the UP it is understood that estimates done during inception are not dependable (this is true of all methods, but the UP acknowledges it). Early inception estimates merely provide guidance if the project is worthy of some real investigation in elaboration, to generate a good estimate. After the first elaboration iteration there is some realistic information to produce a rough estimate. After the second iteration, the estimate starts to develop credibility (see Figure 40.4).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图 40.4.估算和项目阶段。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              有用的估计需要对一些细化迭代进行投资。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Useful estimates require investment in some elaboration iterations.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              这并不意味着尝试早期、准确的估计是不可能的或毫无价值。如果可能的话,非常好。然而,大多数组织并不认为情况并非如此,原因包括不断引入新技术、新颖的应用程序和许多其他复杂性。因此,UP 提倡在生成用于项目规划和预算的估计之前进行一些现实的阐述工作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is not to imply that it is impossible or worthless to attempt early, accurate estimates. If possible, very good. However, most organizations do not find this to be the case, for reasons that include continuous introduction of new technologies, novel applications, and many other complications. Thus, the UP advocates some realistic work in elaboration before generating estimates used for project planning and budgeting.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                40.6. 组织工程工件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                40.6. Organizing Project Artifacts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UP 根据学科组织文物。用例模型和补充规范属于需求学科。软件开发计划是项目管理规则的一部分,依此类推。因此,在版本控制和目录系统中组织文件夹以反映学科,并将学科的工件放在相关的学科文件夹中(参见图 40.5)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The UP organizes artifacts in terms of disciplines. The Use-Case Model and Supplementary Specifications are in the Requirements discipline. The Software Development Plan is part of the Project Management discipline, and so forth. Therefore, organize folders in your version control and directory system to reflect the disciplines, and place the artifacts of a discipline within the related discipline folder (see Figure 40.5).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                图 40.5.将 UP 工件组织到与其学科对应的文件夹中。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                此组织适用于大多数非实现元素。由于各种实现原因,某些实现工件(例如实际的数据库或可执行文件)通常位于不同的位置。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This organization works for most non-implementation elements. Some implementation artifacts, such as the actual database or executable files, are commonly found in different locations for a variety of implementation reasons.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                指引

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Guideline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                每次迭代后,使用版本控制工具创建这些文件夹中所有元素(包括源代码)的标记和冻结检查点。每个工件将有一个 “iteration-1”、“iteration-2” 等版本。为了以后估计团队速度(在这个项目或其他项目中),这些检查点提供了每次迭代完成了多少工作的原始数据。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                After each iteration, use the version control tool to create a labeled and frozen checkpoint of all the elements in these folders (including source code). There will be an "iteration-1," "iteration-2," and so on, version of each artifact. For later estimation of team velocity (on this or other projects), these checkpoints provide raw data of how much work got done per iteration.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  40.7. 你知道你不理解迭代计划的时候......

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  40.7. You Know You Didn't Understand Iterative Planning When…

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 所有迭代都经过推测性的详细规划,并预测了每次迭代的工作和目标。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • All the iterations are speculatively planned in detail, with the work and objectives for each iteration predicted.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 预计开始时的早期估计或第一次迭代的阐述是可靠的,并用于做出长期项目承诺;概括地说,对于琐碎或轻量级的调查,预计会有可靠的估计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Early estimates in inception or the first iteration of elaboration are expected to be reliable, and are used to make long-term project commitments; to generalize, reliable estimates are expected with trivial or light-weight investigation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • 在早期迭代中解决简单的问题或低风险的问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Easy problems or low-risk issues are tackled in early iterations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  如果组织的估算和规划过程如下所示,则表示 UP 中的规划不被理解:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  If an organization's estimation and planning process looks something like the following, planning in the UP was not understood:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  在年度规划阶段开始时,在高级别确定新系统或功能;例如,“用于帐户管理的 Web 系统”。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  技术经理有很短的时间来推测性地估计大型、昂贵或有风险的项目(通常涉及新技术)的工作量和持续时间。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  项目的计划和预算是针对当年制定的。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  4.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  当实际项目与原始估计不匹配时,利益相关者会感到担忧。转到步骤 1。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  这种方法缺乏 UP 所提倡的基于严肃调查的现实和迭代精炼的估计。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This approach lacks realistic and iteratively refined estimation based upon serious investigation as promoted by the UP.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    40.8. 推荐资源

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    40.8. Recommended Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Larman 的 Agile and Iterative Development: A Manager's Guide 除了瀑布失败的广泛证据和迭代方法的优势外,还提供了许多实践技巧。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Agile and Iterative Development: A Manager's Guide by Larman provides many practice tips, in addition to the wide-spread evidence of the failure of the waterfall, and the advantage of iterative methods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Coplien 和 Harrison 编写的《敏捷软件开发的组织模式》总结了许多成功的迭代和敏捷过程以及项目管理技巧。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Organizational Patterns of Agile Software Development by Coplien and Harrison summarizes many successful iterative and agile process and project management tips.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Royce 的《软件项目管理:统一框架》为项目规划和管理提供了迭代和 UP 视角。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Software Project Management: A Unified Framework by Royce provides an iterative and UP perspective on project planning and management.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Cockburn 的 Surviving Object-Oriented Projects: A Manager's Guide 包含有关迭代规划以及向迭代和对象技术项目过渡的更多有用信息。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Cockburn's Surviving Object-Oriented Projects: A Manager's Guide contains more useful information on iterative planning, and the transition to iterative and object technology projects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Beck 和 Fowler 编写的 Planning Extreme Programming 是另一个很好的资源。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Planning Extreme Programming by Beck and Fowler is another good resource.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Kruchten 的 The Rational Unified Process: An Introduction 包含专门针对 UP 中的规划和项目管理的有用章节。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Kruchten's The Rational Unified Process: An Introduction contains useful chapters specifically on planning and project management in the UP.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    需要注意的是,有些书声称要讨论 “迭代开发” 或 “统一过程” 的规划,但实际上掩盖了瀑布式或预测性规划方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As a caution, there are some books that purport to discuss planning for "iterative development" or the "Unified Process" that actually belie a waterfall or predictive approach to planning.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    快速发展 [McConnell96] 很好地概述了规划和项目管理以及项目风险中的许多实践和问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Rapid Development [McConnell96] is an excellent overview of many practices and issues in planning and project management, and project risks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      书目

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Bibliography

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Abbot83 Abbott, R. 1983 年。程序设计由 Informal English Descriptions 进行ACM 通讯第 26(11) 卷。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Abbot83 Abbott, R. 1983. Program Design by Informal English Descriptions. Communications of the ACM vol. 26(11).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      AIS77 亚历山大,C.,石川,S. 和西尔弗斯坦,M. 1977。模式 languageTowns-Building-Construction。牛津大学出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      AIS77 Alexander, C., Ishikawa, S. , and Silverstein, M. 1977. A Pattern LanguageTowns-Building-Construction. Oxford University Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00 Ambler, S. 2000.统一的 ProcessElaboration 阶段。劳伦斯,KA.:R&D Books。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00 Ambler, S. 2000. The Unified ProcessElaboration Phase. Lawrence, KA.: R&D Books.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00a Ambler, S., Constantine, L. 2000 年。企业就绪对象 ID统一的 ProcessConstruction 阶段。劳伦斯,KA.:R&D书籍

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00a Ambler, S., Constantine, L. 2000. Enterprise-Ready Object IDs. The Unified ProcessConstruction Phase. Lawrence, KA.: R&D Books

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00b Ambler, S. 2000.白皮书:为关系数据库设计强大的持久层www.ambysoft.com

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler00b Ambler, S. 2000. Whitepaper: The Design of a Robust Persistence Layer For Relational Databases. www.ambysoft.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler02 Ambler, S. 2002 年。敏捷建模,John Wiley & Sons。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ambler02 Ambler, S. 2002. Agile Modeling, John Wiley & Sons.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BDSSS00 Beedle, M., Devos, M., Sharon, Y., Schwaber, K. 和 Sutherland, J. 2000。SCRUM:一种用于超高效软件开发的模式语言程序设计的模式语言第 4 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BDSSS00 Beedle, M., Devos, M., Sharon, Y., Schwaber, K., and Sutherland, J. 2000. SCRUM: A Pattern Language for Hyperproductive Software Development. Pattern Languages of Program Design vol. 4. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BC87 Beck, K. 和 Cunningham, W. 1987 年。将模式语言用于面向对象的程序。泰克技术报告编号CR-87-43 的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BC87 Beck, K., and Cunningham, W. 1987. Using Pattern Languages for Object-Oriented Programs. Tektronix Technical Report No. CR-87-43.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BC89 Beck, K. 和 Cunningham, W. 1989 年。面向对象思维的实验室OOPSLA 会议记录 89SIGPLAN 通知,第 24 卷,第 10 期。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BC89 Beck, K., and Cunningham, W. 1989. A Laboratory for Object-oriented Thinking. Proceedings of OOPSLA 89. SIGPLAN Notices, Vol. 24, No. 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BCK98 Bass, L.、Clements, P. 和 Kazman, R. 1998。软件架构实践。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BCK98 Bass, L., Clements, P., and Kazman, R. 1998. Software Architecture in Practice. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      贝克94 贝克,K. 1994 年。模式和软件开发Dobbs 博士杂志。1994 年 2 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Beck94 Beck, K. 1994. Patterns and Software Development. Dr. Dobbs Journal. Feb 1994.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      贝克00 贝克,K. 2000。极限编程解释拥抱变化。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Beck00 Beck, K. 2000. Extreme Programming ExplainedEmbrace Change. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      贝尔04 贝尔,A. 2004 年。死于 UML 热ACM 队列。2004 年 3 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Bell04 Bell, A. 2004. Death by UML Fever. ACM Queue. March 2004.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BF00 贝克,K.,福勒,M.,2000 年。规划极限编程。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BF00 Beck, K., Fowler, M. , 2000. Planning Extreme Programming. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BJ78 Bjørner, D. 和 Jones, C. 编辑。1978. 维也纳开发方法:元语言计算机科学讲义。第 61 卷。施普林格出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BJ78 Bjørner, D., and Jones, C. editors. 1978. The Vienna Development Method: The Meta-Language, Lecture Notes in Computer Science. vol. 61. Springer-Verlag.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BJR97 Booch, G.、Jacobson, I. 和 Rumbaugh, J. 1997。UML 规范文档。加利福尼亚州圣克拉拉:Rational Software Corp.请参阅 www.rational.com 中的文档。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BJR97 Booch, G., Jacobson, I., and Rumbaugh, J. 1997. The UML specification documents. Santa Clara, CA.: Rational Software Corp. See documents at www.rational.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BMRSS96 Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P., 和 Stal, M. 1996.面向模式的软件体系结构:模式系统。英格兰西萨塞克斯郡:威利。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BMRSS96 Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P., and Stal, M. 1996. Pattern-Oriented Software Architecture: A System of Patterns. West Sussex, England: Wiley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Boehm88 Boehm.生于 1988 年。软件开发和增强的螺旋模型IEEE 计算机。1988 年 5 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Boehm88 Boehm. B. 1988. A Spiral Model of Software Development and Enhancement. IEEE Computer. May 1988.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Boehm00+ Boehm, B. , et al. 2000.使用 COCOMO II 进行软件成本估算。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Boehm00+ Boehm, B. , et al. 2000. Software Cost Estimation with COCOMO II. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch82 Booch, G. 1982 年。面向对象的设计Ada Letters 第 1(3) 卷。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch82 Booch, G. 1982. Object-Oriented Design. Ada Letters vol. 1(3).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch94 Booch, G. 1994 年。面向对象的分析和设计。加利福尼亚州红木城:本杰明/卡明斯。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch94 Booch, G. 1994. Object-Oriented Analysis and Design. Redwood City, CA.: Benjamin/Cummings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch96 Booch, G. 1996 年。Object Solutions:管理面向对象的项目。加利福尼亚州门洛帕克:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Booch96 Booch, G. 1996. Object Solutions: Managing the Object-Oriented Project. Menlo Park, CA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BP88 Boehm, B. 和 Papaccio, P. 1988。了解和控制软件成本IEEE 软件工程汇刊。1988 年 10 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BP88 Boehm, B., and Papaccio, P. 1988. Understanding and Controlling Software Costs. IEEE Transactions on Software Engineering. Oct 1988.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BRJ99 Booch, G.、Rumbaugh, J 和 Jacobson, I. 1999 年。Unified Modeling Language 用户指南。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BRJ99 Booch, G., Rumbaugh, J, and Jacobson, I. 1999. The Unified Modeling Language User Guide. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      布鲁克斯75 布鲁克斯,F. 1975。神话般的男人月。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Brooks75 Brooks, F. 1975. The Mythical Man-Month. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      布朗01 布朗,K.,2001 年。Convert Exception 模式可在 Portland Pattern Reposity, http://c2.com 在线找到。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Brown01 Brown, K., 2001. The Convert Exception pattern is found online at the Portland Pattern Reposity, http://c2.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BW95 Brown, K. 和 Whitenack, B. 1995。Crossing Chasms,用于对象-RDBMS 集成的模式语言,白皮书,Knowledge Systems Corp.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BW95 Brown, K., and Whitenack, B. 1995. Crossing Chasms, A Pattern Language for Object-RDBMS Integration, White Paper, Knowledge Systems Corp.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BW96 Brown, K. 和 Whitenack, B. 1996。穿越裂缝程序设计的模式语言第 2 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      BW96 Brown, K., and Whitenack, B. 1996. Crossing Chasms. Pattern Languages of Program Design vol. 2. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CD94 Cook, S. 和 Daniels, J. 1994。设计对象系统。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CD94 Cook, S., and Daniels, J. 1994. Designing Object Systems. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CDL99 Coad, P., De Luca, J., Lefebvre, E. 1999 年。使用 UML 进行颜色 Java 建模。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CDL99 Coad, P., De Luca, J., Lefebvre, E. 1999. Java Modeling in Color with UML. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CL99 Constantine, L 和 Lockwood, L. 1999 年。使用软件:以使用为中心的设计模型和方法的实用指南。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CL99 Constantine, L, and Lockwood, L. 1999. Software for Use: A Practical Guide to the Models and Methods of Usage-Centered Design. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CMS74 康斯坦丁,L.,迈尔斯,G.和史蒂文斯,W.,1974 年。结构化设计IBM Systems Journal,第 13 卷(第 2 期,1974 年),第 115-139 页。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CMS74 Constantine, L., Myers, G., and Stevens, W. 1974. Structured Design. IBM Systems Journal, vol. 13 (No. 2, 1974),pp. 115-139.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coad92 Coad,第 1992 页。面向对象的模式ACM 通讯,1992 年 9 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coad92 Coad, P. 1992. Object-oriented Patterns. Communications of the ACM, Sept. 1992.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coad95 Coad,第 1995 页。对象模型:策略、模式和应用程序。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coad95 Coad, P. 1995. Object Models: Stategies, Patterns and Applications. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      科克本92 科克本,A. 1992 年。使用自然语言作为面向对象建模和编程的隐喻基础IBM 技术报告 TR-36.0002,1992 年。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cockburn92 Cockburn, A. 1992. Using Natural Language as a Metaphoric Basis for Object-Oriented Modeling and Programming. IBM Technical Report TR-36.0002, 1992.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      科克本97 科克本,A. 1997 年。使用目标构建用例Journal of Object-Oriented Programming(面向对象编程杂志),Sep-Oct 和 Nov-Dec。SIGS 出版物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cockburn97 Cockburn, A. 1997. Structuring Use Cases with Goals. Journal of Object-Oriented Programming, Sep-Oct, and Nov-Dec. SIGS Publications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      科克本01 科克本,A. 2001 年。编写有效的用例。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cockburn01 Cockburn, A. 2001. Writing Effective Use Cases. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coleman+94 Coleman, D. , et al.1994. 面向对象的开发:融合方法。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coleman+94 Coleman, D. , et al. 1994. Object-Oriented Development: The Fusion Method. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      君士坦丁68 君士坦丁。L. 1968 年。模块化编程的分割和设计策略。在 Barnett 和 Constantine(编辑)中,模块化编程:全国研讨会的论文集。马萨诸塞州剑桥:信息与系统出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Constantine68 Constantine. L. 1968. Segmentation and Design Strategies for Modular Programming. In Barnett and Constantine (eds.), Modular Programming: Proceedings of a National Symposium. Cambridge, MA.: Information & Systems Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      君士坦丁94 君士坦丁,L. 1994 年。基本上是这样软件开发 May. CMP Media.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Constantine94 Constantine, L. 1994. Essentially Speaking. Software Development May. CMP Media.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      康威 58 康威,M. 1958 年。通用面向计算机的语言提案ACM 的通信。5-8 第 1 卷,第 10 期,10 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Conway58 Conway, M. 1958. Proposal for a Universal Computer-Oriented Language. Communications of the ACM. 5-8 Volume 1, Number 10, October.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coplien95 Coplien, J. 1995 年。模式的历史。请参阅 http://c2.com/cgi/wiki?HistoryOfPatterns

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coplien95 Coplien, J. 1995. The History of Patterns. See http://c2.com/cgi/wiki?HistoryOfPatterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coplien95a Coplien, J. 1995 年。一种生成式开发过程模式语言程序设计的模式语言第 1 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Coplien95a Coplien, J. 1995. A Generative Development-Process Pattern Language. Pattern Languages of Program Design vol. 1. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CS95 Coplien, J. 和 Schmidt, D.,编辑 1995 年。程序设计的模式语言第 1 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CS95 Coplien, J., and Schmidt, D., eds. 1995. Pattern Languages of Program Design vol. 1. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      坎宁安96 坎宁安,W. 1996 年。剧集:竞争发展的模式语言程序设计的模式语言第 2 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cunningham96 Cunningham, W. 1996. EPISODES: A Pattern Language of Competitive Development. Pattern Languages of Program Design vol. 2. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cutter97 刀具组。1997. 报告:企业对对象技术的使用

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Cutter97 Cutter Group. 1997. Report: The Corporate Use of Object Technology.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CV65 Corbato, F. 和 Vyssotsky, V. 1965。Multics 系统的介绍和概述AFIPS 会议论文集 27,185-196。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      CV65 Corbato, F., and Vyssotsky, V. 1965. Introduction and overview of the Multics system. AFIPS Conference Proceedings 27,185-196.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Dijkstra68 Dijkstra, E. 1968 年。THE-Multiprogramming System 的结构ACM 通讯,11(5)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Dijkstra68 Dijkstra, E. 1968. The Structure of the THE-Multiprogramming System. Communications of the ACM, 11(5).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Eck95 Eck, D. 1995 年。最复杂的机器。A K Paters 有限公司

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Eck95 Eck, D. 1995. The Most Complex Machine. A K Paters Ltd.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒96 福勒,M. 1996 年。分析模式:可重用的对象模型。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler96 Fowler, M. 1996. Analysis Patterns: Reusable Object Models. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒99 福勒,M. 1999 年。重构:改进现有代码的设计。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler99 Fowler, M. 1999. Refactoring: Improving the Design of Existing Code. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒00 福勒,M .2000. 节食你的过程软件开发。十二月。CMP 媒体。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler00 Fowler, M . 2000. Put Your Process on a Diet. Software Development. December. CMP Media.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒01 福勒,M. 2001 年。对象关系持久性服务上的草稿模式www.martinfowler.com

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler01 Fowler, M. 2001. Draft patterns on object-relational persistence services. www.martinfowler.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒02 福勒,M. 2002 年。企业应用程序体系结构的模式。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler02 Fowler, M. 2002. Patterns of Enterprise Application Architecture. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      福勒03 福勒,M. 2003 年。UML Distilled,第 3 版。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fowler03 Fowler, M. 2003. UML Distilled, 3rd edition. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gartner95 舒尔特,R.,1995 年。三层计算架构及其他架构。已发布报告说明 R-401-134。Gartner 集团。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gartner95 Schulte, R. , 1995. Three-Tier Computing Architectures and Beyond. Published Report Note R-401-134. Gartner Group.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gemstone00 Gemstone Corp.,2000 年。www.javasuccess.com 的一组架构模式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gemstone00 Gemstone Corp., 2000. A set of architectural patterns at www.javasuccess.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GHJV95 Gamma, E.、Helm, R.、Johnson, R. 和 Vlissides, J. 1995。设计模式。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GHJV95 Gamma, E., Helm, R., Johnson, R., and Vlissides, J. 1995. Design Patterns. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gilb88 Gilb, T. 1988 年。软件工程管理原理。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gilb88 Gilb, T. 1988. Principles of Software Engineering Management. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GK00 Guiney, E. 和 Kulak, D. 2000。用例:上下文中的需求。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GK00 Guiney, E., and Kulak, D. 2000. Use Cases: Requirements in Context. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GK76 Goldberg, A. 和 Kay, A. 1976 年。Smalltalk-72 使用说明书。施乐帕洛阿尔托研究中心。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GK76 Goldberg, A., and Kay, A. 1976. Smalltalk-72 Instruction Manual. Xerox Palo Alto Research Center.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GL00 Guthrie, R. 和 Larman, C. 2000 年。Java 2 性能和惯用语指南。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GL00 Guthrie, R., and Larman, C. 2000. Java 2 Performance and Idiom Guide. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      格雷迪92 格雷迪,R. 1992 年。用于项目管理和流程改进的实用软件指标。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Grady92 Grady, R. 1992. Practical Software Metrics for Project Management and Process Improvement. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Groso00 格罗索,W. 2000。Name The Problem Not The Thrower 异常模式可在 Portland Pattern Reposity, http://c2.com 在线找到。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Groso00 Grosso, W. 2000. The Name The Problem Not The Thrower exceptions pattern is found online at the Portland Pattern Reposity, http://c2.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GW89 Gause, D. 和 Weinberg, G. 1989 年。探索需求。纽约州:多塞特宫。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GW89 Gause, D., and Weinberg, G. 1989. Exploring Requirements. NY, NY.: Dorset House.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      哈里森98 哈里森,N. 1998 年。记录诊断消息的模式程序设计的模式语言第 3 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Harrison98 Harrison, N. 1998. Patterns for Logging Diagnostic Messages. Pattern Languages of Program Design vol. 3. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Hay96 Hay, D. 1996 年。数据模型模式:思维惯例。纽约州:多塞特宫。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Hay96 Hay, D. 1996. Data Model Patterns: Conventions of Thought. NY, NY.: Dorset House.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      海史密斯00 海史密斯,J. 2000。自适应软件开发:管理复杂系统的协作方法。纽约州:多塞特宫。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Highsmith00 Highsmith, J. 2000. Adaptive Software Development: A Collaborative Approach to Managing Complex Systems. NY, NY.: Dorset House.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Hohman03 Hohman, L. 2003 年。超越软件架构:创建和维护成功的解决方案。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Hohman03 Hohman, L. 2003. Beyond Software Architecture: Creating and Sustaining Winning Solutions. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      HNS00 Hofmeister, C.、Nord, R. 和 Soni, D. 2000。应用软件架构。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      HNS00 Hofmeister, C., Nord, R., and Soni, D. 2000. Applied Software Architecture. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      杰克逊95 杰克逊,M. 1995。软件要求和规范。纽约州:ACM 出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Jackson95 Jackson, M. 1995. Software Requirements and Specification. NY, NY.: ACM Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      雅各布森92 雅各布森, I. , et al.1992. 面向对象的软件工程:一种用例驱动的方法。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Jacobson92 Jacobson, I. , et al. 1992. Object-Oriented Software Engineering: A Use Case Driven Approach. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      JAH00 Jeffries, R., Anderson, A., Hendrickson, C. 2000 年。已安装极限编程。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      JAH00 Jeffries, R., Anderson, A., Hendrickson, C. 2000. Extreme Programming Installed. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      JBR99 Jacobson, I.、Booch, G. 和 Rumbaugh, J. 1999。统一的软件开发流程。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      JBR99 Jacobson, I., Booch, G., and Rumbaugh, J. 1999. The Unified Software Development Process. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      约翰逊02 约翰逊,J. 2002 年。ROIIt's Your Job,XP 2002,意大利撒丁岛。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Johnson02 Johnson, J. 2002. ROIIt's Your Job, XP 2002, Sardinia, Italy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      琼斯97 琼斯,C.,1997 年。Applied Software Measurement.纽约州:麦格劳-希尔。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Jones97 Jones, C. , 1997. Applied Software Measurement. NY, NY.: McGraw-Hill.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      琼斯98 琼斯,C. 1998 年。估算软件成本。纽约州:麦格劳-希尔。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Jones98 Jones, C. 1998. Estimating Software Costs. NY, NY.: McGraw-Hill.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kay68 Kay, A. 1968 年。FLEX,一种灵活的可扩展语言。M.Sc. 论文,犹他大学电气工程。5 月(大学缩微胶卷)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kay68 Kay, A. 1968. FLEX, a flexible extensible language. M.Sc. thesis, Electrical Engineering, University of Utah. May. (Univ. Microfilms).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      KL01 Kruchten, P 和 Larman, C. 如何用理性统一过程失败:痛苦和苦难的 7 个步骤。(德语)Objekt spektrum.2001 年 6 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      KL01 Kruchten, P, and Larman, C. How to Fail with the Rational Unified Process: 7 Steps to Pain and Suffering. (in German) Objekt Spektrum. June 2001.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      科维茨99 科维茨,生于 1999 年。实用软件要求。康涅狄格州格林威治:曼宁。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kovitz99 Kovitz, B. 1999. Practical Software Requirements. Greenwich, CT.: Manning.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kruchten00 Kruchten,第 2000 页。The Rational Unified Process简介,第 2 版。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kruchten00 Kruchten, P. 2000. The Rational Unified ProcessAn Introduction, 2nd edition. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kruchten95 Kruchten,第 1995 页。建筑的 4+1 视图模型IEEE 软件 12(6)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Kruchten95 Kruchten, P. 1995. The 4+1 View Model of Architecture. IEEE Software 12(6).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      拉科斯96 拉科斯,J. 1996 年。大规模 C++ 软件设计。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Lakos96 Lakos, J. 1996. Large-Scale C++ Software Design. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      拉曼03 拉曼,C. 2003 年。敏捷和迭代开发:经理指南。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Larman03 Larman, C. 2003. Agile and Iterative Development: A Manager's Guide. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      拉曼04 拉曼,C. 2004 年。UML 是什么和不是什么JavaPro 杂志。2004 年 3 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Larman04 Larman, C. 2004. What UML Is and Isn't. JavaPro Magazine. March 2004.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      LB03 Larman, C. 和 Basili, V. 迭代和增量开发:简史IEEE 计算机,2003 年 6 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      LB03 Larman, C., and Basili, V. Iterative and Incremental Development: A Brief History, IEEE Computer, June 2003.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Lieberherr88 Lieberherr, K., Holland, I, and Riel, A. 1988 年。面向对象的编程:客观的风格感OOPSLA 88 会议论文集。纽约州:ACM SIGPLAN。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Lieberherr88 Lieberherr, K., Holland, I, and Riel, A. 1988. Object-Oriented Programming: An Objective Sense of Style. OOPSLA 88 Conference Proceedings. NY, NY.: ACM SIGPLAN.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      李斯科夫88 李斯科夫,生于 1988 年。数据抽象和层次结构SIGPLAN 通知,23,5(1988 年 5 月)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Liskov88 Liskov, B. 1988. Data Abstraction and Hierarchy, SIGPLAN Notices, 23,5 (May, 1988).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      LW00 Leffingwell, D. 和 Widrig, D. 2000。管理软件需求:统一的方法。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      LW00 Leffingwell, D., and Widrig, D. 2000. Managing Software Requirements: A Unified Approach. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      麦科马克01 麦科马克,A. 2001 年。有效的产品开发实践麻省理工学院斯隆管理评论。第 42 卷,第 2 期。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MacCormack01 MacCormack, A. 2001. Product-Development Practices That Work. MIT Sloan Management Review. Volume 42, Number 2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      马丁95 马丁,R. 1995。使用 Booch 方法设计面向对象的 C++ 应用程序。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Martin95 Martin, R. 1995. Designing Object-Oriented C++ Applications Using the Booch Method. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      麦康奈尔96 麦康奈尔,S. 1996 年。快速发展。华盛顿州雷德蒙德:Microsoft Press。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      McConnell96 McConnell, S. 1996. Rapid Development. Redmond, WA.: Microsoft Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      迈耶88 迈耶,生于 1988 年。面向对象的软件构造,第一版。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Meyer88 Meyer, B. 1988. Object-Oriented Software Construction, first edition. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MO95 Martin, J. 和 Odell, J. 1995 年。面向对象的方法:基础。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MO95 Martin, J., and Odell, J. 1995. Object-Oriented Methods: A Foundation. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Moreno97 Moreno, A. M. 文本规范中的面向对象分析。第 9 届软件工程与知识工程国际会议论文集,马德里,6 月 17-20 日(1997 年)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Moreno97 Moreno, A. M. Object Oriented Analysis from Textual Specifications. Proceedings of the 9th International Conference on Software Engineering and Knowledge Engineering, Madrid, June 17-20 (1997).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MP84 McMenamin, S. 和 Palmer, J. 1984 年。基本系统分析。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MP84 McMenamin, S., and Palmer, J. 1984. Essential Systems Analysis. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MW89 1989 年。Merriam-Webster 词典。马萨诸塞州斯普林菲尔德:Merriam-Webster。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      MW89 1989. The Merriam-Webster Dictionary. Springfield, MA.: Merriam-Webster.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      尼克松90 尼克松,R. 1990。六次危机。纽约州:试金石出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Nixon90 Nixon, R. 1990. Six Crises. NY, NY.: Touchstone Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OMG03a 对象管理组,2003 年。UML 2.0 基础结构规范www.omg.org

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OMG03a Object Management Group, 2003. UML 2.0 Infrastructure Specification. www.omg.org.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OMG03b 对象管理组,2003 年。UML 2.0 上层结构规范www.omg.org

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      OMG03b Object Management Group, 2003. UML 2.0 Superstructure Specification. www.omg.org.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      帕金森病58 帕金森,N. 1958 年。帕金森定律:追求进步,伦敦,约翰·默里。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Parkinson58 Parkinson, N. 1958. Parkinson's Law: The Pursuit of Progress, London, John Murray.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Parnas72 Parnas,卒于 1972 年。关于将系统分解为模块的标准ACM 通讯,第 5 卷,第 12 期,1972 年 12 月。ACM 的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Parnas72 Parnas, D. 1972. On the Criteria To Be Used in Decomposing Systems Into Modules, Communications of the ACM, Vol. 5, No. 12, December 1972. ACM.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      PM92 Putnam, L. 和 Myers, W. 1992 年。卓越措施:在预算范围内按时提供可靠的软件。尤尔登出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      PM92 Putnam, L., and Myers, W. 1992. Measures for Excellence: Reliable Software on Time, Within Budget. Yourdon Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pree95 Pree, W. 1995 年。面向对象的软件开发的设计模式。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pree95 Pree, W. 1995. Design Patterns for Object-Oriented Software Development. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      伦泽尔97 伦泽尔,K. 1997。业务信息系统的错误处理:一种模式语言。在线 http://www.objectarchitects.de/arcus/cookbook/exhandling/

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Renzel97 Renzel, K. 1997. Error Handling for Business Information Systems: A Pattern Language. Online at http://www.objectarchitects.de/arcus/cookbook/exhandling/.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rising00 Rising, L. 2000 年。图案年鉴 2000 年。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rising00 Rising, L. 2000. Pattern Almanac 2000. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RJB99 Rumbaugh, J.、Jacobson, I. 和 Booch, G. 1999 年。统一建模语言参考手册。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RJB99 Rumbaugh, J., Jacobson, I., and Booch, G. 1999. The Unified Modeling Language Reference Manual. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RJB04 Rumbaugh, J.、Jacobson, I. 和 Booch, G. 2004 年。统一建模语言参考手册,2e。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RJB04 Rumbaugh, J., Jacobson, I., and Booch, G. 2004. The Unified Modeling Language Reference Manual, 2e. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      罗斯97 罗斯,R. 1997。业务规则手册:分类、定义和建模规则。Business Rule Solutions, Inc. 公司

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ross97 Ross, R. 1997. The Business Rule Book: Classifying, Defining and Modeling Rules. Business Rule Solutions Inc.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      罗伊斯70 罗伊斯,W. 1970。管理大型软件系统的开发IEEE WESCON 会议记录。1970 年 8 月。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Royce70 Royce, W. 1970. Managing the Development of Large Software Systems. Proceedings of IEEE WESCON. Aug 1970.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rumbaugh91 Rumbaugh, J. , et al.1991. 面向对象的建模和设计。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rumbaugh91 Rumbaugh, J. , et al. 1991. Object-Oriented Modelling and Design. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RUP:Rational 统一流程产品。RUP 的基于浏览器的在线文档,由 IBM 出售,以前由 Rational Corp. 出售。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RUP The Rational Unified Process Product. The browser-based online documentation for the RUP, sold by IBM, and previously by Rational Corp.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rumbaugh97 Rumbaugh, J. 1997 年。模型面向对象编程杂志1997 年 5 月。纽约州:SIGS 出版物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Rumbaugh97 Rumbaugh, J. 1997. Models Through the Development Process. Journal of Object-Oriented Programming May 1997. NY, NY: SIGS Publications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Shaw96 Shaw, M. 1996 年。软件架构的一些模式程序设计的模式语言第 2 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Shaw96 Shaw, M. 1996. Some Patterns for Software Architectures. Pattern Languages of Program Design vol. 2. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      斯坦迪什94 吉姆·约翰逊 .1994. 混沌:绘制信息技术的海洋。已发布的报告。斯坦迪什集团

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Standish94 Jim Johnson . 1994. Chaos: Charting the Seas of Information Technology. Published Report. The Standish Group

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SW98 Schneider, G. 和 Winters, J. 1998 年。应用用例:实用指南。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      SW98 Schneider, G., and Winters, J. 1998. Applying Use Cases: A Practical Guide. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      托马斯01 托马斯,M. 2001 年。IT 项目要么沉沦,要么游泳英国计算机学会评论

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thomas01 Thomas, M. 2001. IT Projects Sink or Swim. British Computer Society Review.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      TK78 Tsichiritzis, D. 和 Klug, A. ANSI/X3/SPARC DBMS 框架:数据库管理系统研究组的报告信息系统,3 1978 年。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      TK78 Tsichiritzis, D., and Klug, A. The ANSI/X3/SPARC DBMS framework: Report of the study group on database management systems. Information Systems, 3 1978.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Tufte92 Tufte, E. 1992 年。定量信息的可视化显示。图形出版社。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Tufte92 Tufte, E. 1992. The Visual Display of Quantitative Information. Graphics Press.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      VCK96 Vlissides, J. 等人,1996 年。模式程序设计语言第 2 卷。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      VCK96 Vlissides, J. , et al. 1996. Patterns Languages of Program Design vol. 2. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Wirfs-Brock93 Wirfs-Brock, R. 1993 年。设计场景:为用例框架提供案例Smalltalk 报告1993 年 11 月至 12 月。纽约州:SIGS 出版物。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Wirfs-Brock93 Wirfs-Brock, R. 1993. Designing Scenarios: Making the Case for a Use Case Framework. Smalltalk Report Nov-Dec 1993. NY, NY: SIGS Publications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WK99 Warmer, J. 和 Kleppe, A. 1999 年。对象约束语言:使用 UML 进行精确建模。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WK99 Warmer, J., and Kleppe, A. 1999. The Object Constraint Language: Precise Modeling With UML. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WM02 Wirfs-Brock, R. 和 McKean, A. 2002 年。对象设计:角色、职责和协作。马萨诸塞州雷丁:艾迪生-卫斯理。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WM02 Wirfs-Brock, R., and McKean, A. 2002. Object Design: Roles, Responsibilities, and Collaborations. Reading, MA.: Addison-Wesley.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WWW90 Wirfs-Brock, R.、Wilkerson, B. 和 Wiener, L. 1990 年。设计面向对象的软件。新泽西州恩格尔伍德悬崖:Prentice-Hall。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WWW90 Wirfs-Brock, R., Wilkerson, B., and Wiener, L. 1990. Designing Object-Oriented Software. Englewood Cliffs, NJ.: Prentice-Hall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        词汇表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Glossary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        抽象类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        abstract class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一个只能用作其他类的超类的类;除作为子类的实例外,不得创建抽象类的任何对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A class that can be used only as a superclass of some other class; no objects of an abstract class may be created except as instances of a subclass.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        抽象化
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        abstraction

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        集中相似事物的本质或一般品质的行为。此外,由此产生的事物的基本特征。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The act of concentrating the essential or general qualities of similar things. Also, the resulting essential characteristics of a thing.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        活动对象
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        active object

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        具有自己的控制线程的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An object with its own thread of control.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        集合体
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        aggregation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        表示整体部分关系和(通常)生命周期包含的关联属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A property of an association representing a whole-part relationship and (usually) life-time containment.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        分析
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对域的调查,生成描述其静态和动态特征的模型。它强调的是 “什么” 的问题,而不是 “如何” 的问题。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An investigation of a domain that results in models describing its static and dynamic characteristics. It emphasizes questions of "what," rather than "how."





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        建筑
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        architecture

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        非正式地,对系统的组织、动机和结构的描述。开发软件系统涉及许多不同级别的体系结构,从物理硬件体系结构到应用程序框架的逻辑体系结构。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Informally, a description of the organization, motivation, and structure of a system. Many different levels of architectures are involved in developing software systems, from physical hardware architecture to the logical architecture of an application framework.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        协会
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        association

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对两个类的对象之间的一组相关链接的描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A description of a related set of links between objects of two classes.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        属性
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        attribute

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类的命名特征或属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A named characteristic or property of a class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UML 中,“共享相同属性、操作、方法、关系和行为的一组对象的描述符”[RJB99]。可用于表示软件或概念元素。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UML, "The descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior" [RJB99]. May be used to represent software or conceptual elements.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        class 属性
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        class attribute

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对于类的所有实例都相同的特征或属性。此信息通常存储在类定义中。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A characteristic or property that is the same for all instances of a class. This information is usually stored in the class definition.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类层次结构
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        class hierarchy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类之间的继承关系的描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A description of the inheritance relations between classes.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类方法
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        class method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义类本身的行为(而不是其实例的行为)的方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A method that defines the behavior of the class itself, as opposed to the behavior of its instances.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        分类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        classification

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义类与其实例之间的关系。分类映射标识类的扩展。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Defines a relation between a class and its instances. The classification mapping identifies the extension of a class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        协作
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        collaboration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        两个或多个对象参与客户端/服务器关系以提供服务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Two or more objects that participate in a client/server relationship in order to provide a service.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        组成
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        composition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类的定义,其中每个实例都由其他对象组成。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The definition of a class in which each instance is comprised of other objects.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        concept

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一类想法或事物。在本书中,用于指定现实世界的事物而不是软件实体。概念的内涵是对其属性、操作和语义的描述。概念的扩展是作为概念成员的实例或示例对象的集合。通常定义为 domain class 的同义词。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A category of ideas or things. In this book, used to designate real-world things rather than software entities. A concept's intension is a description of its attributes, operations and semantics. A concept's extension is the set of instances or example objects that are members of the concept. Often defined as a synonym for domain class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        concrete 类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        concrete class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        可以具有实例的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A class that can have instances.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        约束
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        constraint

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        元素的限制或条件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A restriction or condition on an element.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        构造 函数
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        constructor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 C++ 或 Java 中创建类的实例时调用的特殊方法。构造函数通常执行初始化操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A special method called whenever an instance of a class is created in C++ or Java. The constructor often performs initialization actions.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        容器类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        container class

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        用于保存和操作对象集合的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A class designed to hold and manipulate a collection of objects.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        合同
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        contract

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义适用于操作或方法的使用的责任和后置条件。还用于指代与接口相关的所有条件的集合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Defines the responsibilities and postconditions that apply to the use of an operation or method. Also used to refer to the set of all conditions related to an interface.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        耦合
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        coupling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        元素(例如类、包、子系统)之间的依赖关系,通常是由于元素之间协作提供服务而产生的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A dependency between elements (such as classes, packages, subsystems), typically resulting from collaboration between the elements to provide a service.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        代表团
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        delegation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一个对象可以向另一个对象发出消息以响应消息的概念。因此,第一个对象将责任委托给第二个对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The notion that an object can issue a message to another object in response to a message. The first object therefore delegates the responsibility to the second object.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        派生
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        derivation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        通过引用现有类来定义新类,然后添加属性和方法的过程 现有类是超类;新类称为 Subclass 或 Derived 类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The process of defining a new class by reference to an existing class and then adding attributes and methods The existing class is the superclass; the new class is referred to as the subclass or derived class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        设计
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        使用分析产品生成用于实现系统的规范的过程。系统将如何工作的逻辑描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A process that uses the products of analysis to produce a specification for implementing a system. A logical description of how a system will work.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        domain

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义特定主题或感兴趣区域的正式边界。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A formal boundary that defines a particular subject or area of interest.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        封装
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        encapsulation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一种用于隐藏某些元素(如对象或子系统)的数据、内部结构和实现详细信息的机制。与对象的所有交互都是通过操作的公共接口进行的。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A mechanism used to hide the data, internal structure, and implementation details of some element, such as an object or subsystem. All interaction with an object is through a public interface of operations.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        事件
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        event

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一个值得注意的事件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A noteworthy occurrence.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        外延
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        extension

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念所适用的对象集。扩展中的对象是概念的示例或实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The set of objects to which a concept applies. The objects in the extension are the examples or instances of the concept.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        框架
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一组协作的抽象类和具体类,可用作解决相关问题系列的模板。它通常通过子类化来扩展,以实现特定于应用程序的行为。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A set of collaborating abstract and concrete classes that may be used as a template to solve a related family of problems. It is usually extended via subclassing for application-specific behavior.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        普遍化
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        generalization

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        识别概念之间的共性并定义超类 (一般概念) 和子类 (专业概念) 关系的活动。这是一种在概念之间构建分类的方法,然后在类层次结构中对其进行说明。概念子类在内涵和扩展方面符合概念超类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The activity of identifying commonality among concepts and defining a superclass (general concept) and subclass (specialized concept) relationships. It is a way to construct taxonomic classifications among concepts, which are then illustrated in class hierarchies. Conceptual subclasses conform to conceptual superclasses in terms of intension and extension.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        遗产
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        inheritance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        面向对象编程语言的一种功能,通过该功能,类可以从更通用的超类中分化出来。子类会自动获取 superclasses 中的属性和方法定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A feature of object-oriented programming languages by which classes may be specialized from more general superclasses. Attributes and method definitions from superclasses are automatically acquired by the subclass.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        实例
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        instance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        类的单个成员。在 UML 中,称为对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An individual member of a class. In the UML, called an object.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        实例方法
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        instance method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        范围为实例的方法。通过向实例发送消息来调用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A method whose scope is an instance. Invoked by sending a message to an instance.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        实例变量
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        instance variable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 Java 和 Smalltalk 中使用时,实例的属性。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As used in Java and Smalltalk, an attribute of an instance.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        实例
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        instantiation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        创建类的实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The creation of an instance of a class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        内涵
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        intension

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念的定义。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The definition of a concept.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        接口
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        interface

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        公共操作的一组签名。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A set of signatures of public operations.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        链接
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        link

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        两个对象之间的连接;关联的实例。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A connection between two objects; an instance of an association.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        消息
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        message

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象通信的机制;通常是执行方法的请求。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The mechanism by which objects communicate; usually a request to execute a method.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        元模型
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        metamodel

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        定义其他模型的模型。UML 元模型定义了 UML 的元素类型,例如 Classifier。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A model that defines other models. The UML metamodel defines the element types of the UML, such as Classifier.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        方法
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        method

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UML 中,类的操作的特定实现或算法。非正式地,为响应消息而执行的软件过程。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UML, the specific implementation or algorithm of an operation for a class. Informally, the software procedure that can be executed in response to a message.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对主题区域的静态和/或动态特征的描述,通过多个视图(通常是图表或文本)进行描述。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A description of static and/or dynamic characteristics of a subject area, portrayed through a number of views (usually diagrammatic or textual).





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多样性
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        multiplicity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        允许参与关联的对象数。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The number of objects permitted to participate in an association.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UML 中,封装状态和行为的类的实例。更非正式地说,一个事物的例子。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UML, an instance of a class that encapsulates state and behavior. More informally, an example of a thing.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象标识
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object identity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象存在独立于与对象关联的任何值的功能。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The feature that the existence of an object is independent of any values associated with the object.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        面向对象的分析
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object-oriented analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        根据域概念 (例如概念类、关联和状态更改) 对问题域或系统进行调查。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The investigation of a problem domain or system in terms of domain concepts, such as conceptual classes, associations, and state changes.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        面向对象的设计
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object-oriented design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        根据软件对象 (例如,它们的类、属性、方法和协作) 对逻辑软件解决方案的规范。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The specification of a logical software solution in terms of software objects, such as their classes, attributes, methods, and collaborations.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        面向对象的编程语言
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        object-oriented programming language

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一种支持封装、继承和多态性概念的编程语言。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A programming language that supports the concepts of encapsulation, inheritance, and polymorphism.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        OID 类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        OID

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象标识符。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Object Identifier.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        操作
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        operation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在 UML 中,“可以调用对象来执行的转换或查询的规范”[RJB99]。操作具有由其名称和参数指定的签名,并通过消息调用该签名。方法是具有特定算法的操作的实现。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the UML, "a specification of a transformation or query that an object may be called to execute" [RJB99]. An operation has a signature, specified by its name and parameters, and it is invoked via a message. A method is an implementation of an operation with a specific algorithm.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        模式
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        pattern

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        问题的命名描述、解决方案、何时应用解决方案以及如何在新上下文中应用解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A named description of a problem, solution, when to apply the solution, and how to apply the solution in new contexts.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        坚持
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        persistence

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象状态的持久存储。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The enduring storage of the state of an object.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        persistent 对象
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        persistent object

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        可以在创建它的进程或线程中幸存下来的对象。持久性对象在被显式删除之前一直存在。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An object that can survive the process or thread that created it. A persistent object exists until it is explicitly deleted.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多态操作
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        polymorphic operation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        由两个或多个类以不同方式实现的相同操作。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The same operation implemented differently by two or more classes.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        多态性
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        polymorphism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        两个或多个对象类可以使用多态操作以不同的方式响应同一消息的概念。此外,还能够定义多态运算。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The concept that two or more classes of objects can respond to the same message in different ways, using polymorphic operations. Also, the ability to define polymorphic operations.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        后条件
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        postcondition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在操作完成后必须保持 true 的约束。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A constraint that must hold true after the completion of an operation.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        前提
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        precondition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        在请求操作之前必须为 true 的约束。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A constraint that must hold true before an operation is requested.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        私人
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        private

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一种范围机制,用于限制对类成员的访问,以便其他对象无法看到它们。通常应用于所有属性和某些方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A scoping mechanism used to restrict access to class members so that other objects cannot see them. Normally applied to all attributes, and to some methods.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        公共
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        public

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        一种范围机制,用于使成员可供其他对象访问。通常应用于某些方法,但不适用于属性,因为 public 属性违反了封装。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A scoping mechanism used to make members accessible to other objects. Normally applied to some methods, but not to attributes, since public attributes violate encapsulation.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        纯数据值
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        pure data values

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        唯一实例标识没有意义的数据类型,例如数字、布尔值和字符串。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Data types for which unique instance identity is not meaningful, such as numbers, booleans, and strings.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        合格协会
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        qualified association

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        其成员资格由限定符的值分区的关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An association whose membership is partitioned by the value of a qualifier.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        接收器
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        receiver

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        消息发送到的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The object to which a message is sent.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        递归关联
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        recursive association

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        源和目标为同一对象类的关联。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        An association where the source and the destination are the same object class.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        责任
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        responsibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        由元素(例如类或子系统)提供的 Knowing 或 Doing 服务或一组服务;责任体现了元素的一个或多个目的或义务。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A knowing or doing service or group of services provided by an element (such as a class or subsystem); a responsibility embodies one or more of the purposes or obligations of an element.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        角色
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        role

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        关联的命名端,用于指示其用途。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A named end of an association to indicate its purpose.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        state

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        事件之间对象的条件。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The condition of an object between events.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        状态转换
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        state transition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        对象的状态更改;可以由事件发出信号的东西。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A change of state for an object; something that can be signaled by an event.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        亚纲
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        subclass

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另一个类 (superclass) 的特化。子类继承了 superclass 的属性和方法。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A specialization of another class (the superclass). A subclass inherits the attributes and methods of the superclass.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        subtype

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念超类。另一种类型 (超类型) 的特化,符合超类型的内涵和扩展。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A conceptual superclass. A specialization of another type (the supertype) that conforms to the intension and extension of the supertype.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        超类
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        superclass

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        另一个类从中继承属性和方法的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A class from which another class inherits attributes and methods.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        超类型
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        supertype

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        概念超类。在泛化-特化关系中,更通用的类型;具有子类型的对象。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A conceptual superclass. In a generalization-specialization relation, the more general type; an object that has subtypes.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        过渡
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        transition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        如果发生指定事件且满足保护条件,则遍历的状态之间的关系。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A relationship between states that is traversed if the specified event occurs and the guard condition met.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        能见度
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        visibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        查看或引用对象的能力。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The ability to see or have reference to an object.





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          前盖内页

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Inside Front Cover

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          统一流程构件和计时示例 (s-start;r-refine)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          学科

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discipline

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          人工制品

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Artifact

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          因塞普。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Incep.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          埃拉布。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Elab.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          常量。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Const.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          反式。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Trans.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          迭 代

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Iteration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          I1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          E1..中文

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          E1..En

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          C1..快递 之 家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          C1..Cn

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          T1..T2 航站楼

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          T1..T2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          业务建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Business Modeling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          域模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Domain Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          要求

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Requirements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          用例模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Use-Case Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          视觉

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Vision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          补充规格

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Supplementary Specification

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          词汇表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Glossary

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          设计模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Design Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          软件架构文档

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          SW Architecture Document

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          数据模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Data Model

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          实现

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Implementation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          实现模型 (code, html, ...)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Implementation Model (code, html, …)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          s

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          r



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          一般责任分配软件模式或原则 (GRASP)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          模式/原理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Pattern/Principle

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Description

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          信息专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Information Expert

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          对象设计和责任分配的一般原则?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A general principle of object design and responsibility assignment?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将责任分配给信息专家具有履行职责所需信息的类。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign a responsibility to the information expertthe class that has the information necessary to fulfill the responsibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          造物主

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          谁创造?(请注意,Factory 是一种常见的替代解决方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who creates? (Note that Factory is a common alternate solution.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如果满足以下条件之一,则分配类 B 创建类 A 实例的责任:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign class B the responsibility to create an instance of class A if one of these is true:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. B 包含 A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. B contains A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. B 记录 A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. B records A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. B 聚合 A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. B aggregates A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          5. B 与 A 紧密结合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          5. B closely uses A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. B 有 A 的初始化数据

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. B has the initializing data for A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Controller

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          UI 层之外的第一个对象接收和协调 (“控件”) 系统操作?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          What first object beyond the UI layer receives and coordinates ("controls") a system operation?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将责任分配给表示以下选项之一的对象:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign the responsibility to an object representing one of these choices:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1. 表示整个 “系统”、“根对象”、运行软件的设备或主要子系统(这些都是 Facade 控制器的变体)。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2. Represents the overall "system," a "root object," a device that the software is running within, or a major subsystem (these are all variations of a facade controller).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3. 表示发生系统操作的用例场景(用例或会话控制器)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4. Represents a use case scenario within which the system operation occurs (a use-case or session controller)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          低耦合 (评价)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Low Coupling (evaluative)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如何减少变更的影响?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How to reduce the impact of change?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          分配职责,使 (不必要的) 耦合保持较低水平。使用此原则来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign responsibilities so that (unnecessary) coupling remains low. Use this principle to evaluate alternatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          高内聚(评估)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          High Cohesion (evaluative)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如何保持对象的焦点、可理解性和可管理性,并作为副作用支持 Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How to keep objects focused, understandable, and manageable, and as a side-effect, support Low Coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          分配责任,以保持高度凝聚力。使用它来评估备选方案。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign responsibilities so that cohesion remains high. Use this to evaluate alternatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          多态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Polymorphism

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当行为因类型而异时,谁负责?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who is responsible when behavior varies by type?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当相关的替代项或行为因类型(类)而异时,将行为使用多态操作的责任分配给行为变化的类型。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When related alternatives or behaviors vary by type (class), assign responsibility for the behaviorusing polymorphic operationsto the types for which the behavior varies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          纯制造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Pure Fabrication

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          当你走投无路,又不想违背高内聚、低耦合时,谁来负责呢?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Who is responsible when you are desperate, and do not want to violate high cohesion and low coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将一组高度内聚的职责分配给一个人工的或方便的 “行为” 类,该类不代表问题域概念的虚构,以支持高内聚、低耦合和重用。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign a highly cohesive set of responsibilities to an artificial or convenience "behavior" class that does not represent a problem domain conceptsomething made up, in order to support high cohesion, low coupling, and reuse.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          间接

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Indirection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如何分配责任避免直接耦合?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How to assign responsibilities to avoid direct coupling?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          将责任分配给一个中间对象,以便在其他组件或服务之间进行调解,以便它们不会直接耦合。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Assign the responsibility to an intermediate object to mediate between other components or services, so that they are not directly coupled.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          受保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Protected Variations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          如何为对象、子系统和系统分配责任,以便这些元素的变化或不稳定不会对其他元素产生不良影响?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How to assign responsibilities to objects, subsystems, and systems so that the variations or instability in these elements do not have an undesirable impact on other elements?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          确定预测变化或不稳定性的点;分配职责以围绕他们创建一个稳定的 “接口”。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Identify points of predicted variation or instability; assign responsibilities to create a stable "interface" around them.



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            封底内侧

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Inside Back Cover

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] []





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              .NET 第 2 个 第 3 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              4+1 视图模型 第 2 个



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              CASE 工具

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              随意 用例



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              抽象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              关联

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              概念 第 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              个 定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              层次结构 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的第 2 个 3 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              映射 来自 DCD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分区

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分区的第

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 个映射 UML 含义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 表示

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              法 类图 第 2 个 第 3 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              类图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              类层次结构 第 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              类方法调用 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分类器名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分类器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的第

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 类操作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              客户端驱动开发

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Coad95

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              COCOMO II

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              代码

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              映射 OO 设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              代码味道

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              凝聚 第二次

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              合作

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在 RDD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              协作图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              条件消息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              示例中

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 个实例创建

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              迭代

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              链接

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              消息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              排序 message to self

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              消息

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              互斥 条件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              序号



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              OO 中 RDD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              集合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中对象的协作 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中编程

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中迭代 n UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              命令模式 2 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              命令-查询分离原则

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注释

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在集合消息到类对象的
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              通信图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              迭代


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              优点和缺点
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              部署图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              通信路径

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              类图中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              隔间 类框中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              隔间

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              组件



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              基于组件的建模

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              复合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              聚合 第 2 个 第 3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              个组合 第 2 个 第 3 个 第 4 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              概念

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              查找

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              查找

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              规范或描述时出错 概念

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              与角色

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              概念类 第二

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              概念模型 第二

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              概念对象模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              具体工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              具体用例 序列图
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的第 2 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              条件消息 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              构造阶段
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注释符号


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的约束


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              容器中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              构造函数(在 Decorator 模式中)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              上下文图第 2 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              持续集成

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              合同

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              示例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指南

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              postcondition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              部分描述

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              合同

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              控制对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              应用程序 2nd 3rd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              臃肿

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              定义

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Convert Exceptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              耦合 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              relation to dependency

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在依赖关系上

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              创建

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              刻板型 Line Creator 2nd 3rd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              application 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              crosscutting concerns



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              休眠

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              高内聚

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              好莱坞原则



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              加入

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              JUnit



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              关键字





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              N+1 视图模型 UML 包中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 命名空间

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 类



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的可导航性箭头

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              导航模型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              节点

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              非功能性要求

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              NUnit 中的补充规范

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              注释





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]





                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              依赖关系

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              组织指南

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              所有权

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              参考

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的包属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              包图 UML 中的第 2 个 3 个

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              包名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分类器名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              图中的参数化类型

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              参数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              交互图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 个参与者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              分区

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              路径名

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式 2nd 3rd 4th 5th

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              抽象工厂

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              适配器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              粗粒度远程接口

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              命令

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              复合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              控制器

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              转换 异常

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              创作者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              自己动手 2nd 3rd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              专家

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Facade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Factory

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              高凝聚力

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              间接层



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              低耦合

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模型-视图 分离

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              名称

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              观察者

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              多态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              保护变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              发布-订阅

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              纯制造

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              重定向 代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              远程代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              单例

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              状态

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              策略

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模板方法

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              虚拟代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              架构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              历史

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              持久化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              持久化框架

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              关键思想

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              物化

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式 - 缓存管理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式 - 对象标识符

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式 - 将对象表示为表

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              表示表中

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              的关系 要求

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              持久对象

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              培养网

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              阶段 计划 2nd 3rd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              物理架构

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的阶段 物理设计

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              规划

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              通信图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的自适应

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              迭代多

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              态性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              in sequence diagrams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              多态性 payment



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              条件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              模式 use case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的隐喻

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              use case

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的前提

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              条件 primary actor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              进程中的最小意外

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              原则私有

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              迭代进程视图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              配置文件

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2nd


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML 第 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              结构中的项目管理
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ,在 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              属性字符串中,用于关联的字符串

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              属性字符串
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              结尾


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在类图中 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              中的

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              2 个受保护属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              保护的变体

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              虚拟代理

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              代理模式

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              公共属性

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              在 UML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              发布-订阅

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              纯制造



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              合格关联 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              限定符 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              质量属性 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              质量场景



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              瀑布式 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WebForms 2nd

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WinForms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Wirfs-Brock93



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              指数

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Index



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [符号] [] [] [] [D] [] [] [] [H] [] [J] [K] [L] [] [编号] [O] [P] [] [R] [S] [T] [] [V] [W] [X]



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XML

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XP 第 2 次 第 3 次

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              xUnit